1// source --> https://vibeudlejning.dk/wp-content/plugins/trustpilot-reviews/review/assets/js/headerScript.min.js?ver=1.0' async='async 2function inIframe(){try{return window.self!==window.top}catch(t){return!1}}function tryParseJson(t){if("string"==typeof t)try{return JSON.parse(t)}catch(t){return!1}return!1}!function(t,e,r,s,i){t.TrustpilotObject=i,t.tp=t.tp||function(){(t.tp.q=t.tp.q||[]).push(arguments)},a=e.createElement(r),a.async=1,a.src=s,a.type="text/java"+r,f=e.getElementsByTagName(r)[0],f.parentNode.insertBefore(a,f)}(window,document,"script",trustpilot_settings.TrustpilotScriptUrl,"tp"),tp("register",trustpilot_settings.key),inIframe()&&window.addEventListener("message",function(t){var e=new URL(window.location).hostname;if(t.data&&-1!==t.origin.indexOf(e))if("undefined"!=typeof TrustpilotPreview){if("string"!=typeof t.data||"submit"!==t.data)return jsonData=tryParseJson(t.data),void(jsonData&&(jsonData.trustbox?TrustpilotPreview.setSettings(jsonData.trustbox):jsonData.customised&&TrustpilotPreview.updateActive(jsonData.customised)));TrustpilotPreview.sendTrustboxes()}else{var r=tryParseJson(t.data);if(r&&r.trustboxes){var s=document.createElement("script");s.type="text/javascript",s.src=trustpilot_settings.WidgetScriptUrl,document.head.appendChild(s);var i=document.createElement("script");i.type="text/javascript",i.onload=function(){const e=t.source.parent.document.getElementById("configuration_iframe").contentWindow;TrustpilotPreview.init([trustpilot_settings.PreviewCssUrl,trustpilot_settings.PreviewWPCssUrl],r,e,t.source)},i.src=trustpilot_settings.PreviewScriptUrl,document.head.appendChild(i)}}}); 3//# sourceMappingURL=headerScript.min.js.map; 4// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/public/lib/pannellum/src/js/pannellum.js?ver=1 5/* 6 * Pannellum - An HTML5 based Panorama Viewer 7 * Copyright (c) 2011-2019 Matthew Petroff 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * of this software and associated documentation files (the "Software"), to deal 11 * in the Software without restriction, including without limitation the rights 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 * copies of the Software, and to permit persons to whom the Software is 14 * furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 * THE SOFTWARE. 26 */ 27 28window.pannellum = (function(window, document, undefined) { 29 30 'use strict'; 31 32 /** 33 * Creates a new panorama viewer. 34 * @constructor 35 * @param {HTMLElement|string} container - The container (div) element for the 36 * viewer, or its ID. 37 * @param {Object} initialConfig - Inital configuration for viewer. 38 */ 39 function Viewer(container, initialConfig) { 40 41 var _this = this; 42 43// Declare variables 44 var config, 45 renderer, 46 preview, 47 isUserInteracting = false, 48 latestInteraction = Date.now(), 49 onPointerDownPointerX = 0, 50 onPointerDownPointerY = 0, 51 onPointerDownPointerDist = -1, 52 onPointerDownYaw = 0, 53 onPointerDownPitch = 0, 54 keysDown = new Array(10), 55 fullscreenActive = false, 56 loaded, 57 error = false, 58 isTimedOut = false, 59 listenersAdded = false, 60 panoImage, 61 prevTime, 62 speed = {'yaw': 0, 'pitch': 0, 'hfov': 0}, 63 animating = false, 64 orientation = false, 65 orientationYawOffset = 0, 66 autoRotateStart, 67 autoRotateSpeed = 0, 68 origHfov, 69 origPitch, 70 animatedMove = {}, 71 externalEventListeners = {}, 72 specifiedPhotoSphereExcludes = [], 73 update = false, // Should we update when still to render dynamic content 74 eps = 1e-6, 75 hotspotsCreated = false, 76 destroyed = false;
77 78 var defaultConfig = { 79 hfov: 100, 80 minHfov: 50, 81 multiResMinHfov: false, 82 maxHfov: 120, 83 pitch: 0, 84 minPitch: undefined, 85 maxPitch: undefined, 86 yaw: 0, 87 minYaw: -180, 88 maxYaw: 180, 89 roll: 0, 90 haov: 360, 91 vaov: 180, 92 vOffset: 0, 93 autoRotate: false, 94 autoRotateInactivityDelay: -1, 95 autoRotateStopDelay: undefined, 96 type: 'equirectangular', 97 northOffset: 0, 98 showFullscreenCtrl: true, 99 dynamic: false, 100 dynamicUpdate: false, 101 doubleClickZoom: true, 102 keyboardZoom: true, 103 mouseZoom: true, 104 showZoomCtrl: true, 105 autoLoad: false, 106 showControls: true, 107 orientationOnByDefault: false, 108 hotSpotDebug: false, 109 backgroundColor: [0, 0, 0], 110 avoidShowingBackground: false, 111 animationTimingFunction: timingFunction, 112 draggable: true, 113 disableKeyboardCtrl: false, 114 crossOrigin: 'anonymous', 115 touchPanSpeedCoeffFactor: 1, 116 capturedKeyNumbers: [16, 17, 27, 37, 38, 39, 40, 61, 107, 109, 173, 187, 189], 117 friction: 0.15 118 }; 119 120// Translatable / configurable strings 121// Some strings contain '%s', which is a placeholder for inserted values 122// When setting strings in external configuration, `\n` should be used instead of `<br>` to insert line breaks 123 defaultConfig.strings = { 124 // Labels 125 loadButtonLabel: 'Click to<br>Load<br>Panorama', 126 loadingLabel: 'Loading...', 127 bylineLabel: ' %s', // One substitution: author 128 129 // Errors 130 noPanoramaError: 'No panorama image was specified.',
vendor: 4,477 bytes, lines 131-218
131 fileAccessError: 'The file %s could not be accessed.', // One substitution: file URL 132 malformedURLError: 'There is something wrong with the panorama URL.', 133 iOS8WebGLError: "Due to iOS 8's broken WebGL implementation, only " + 134 "progressive encoded JPEGs work for your device (this " + 135 "panorama uses standard encoding).", 136 genericWebGLError: 'Your browser does not have the necessary WebGL support to display this panorama.', 137 textureSizeError: 'This panorama is too big for your device! It\'s ' + 138 '%spx wide, but your device only supports images up to ' + 139 '%spx wide. Try another device.' + 140 ' (If you\'re the author, try scaling down the image.)', // Two substitutions: image width, max image width 141 unknownError: 'Unknown error. Check developer console.', 142 }; 143 144// Initialize container 145 container = typeof container === 'string' ? document.getElementById(container) : container; 146 container.classList.add('pnlm-container'); 147 container.tabIndex = 0; 148 149// Create container for ui 150 var uiContainer = document.createElement('div'); 151 uiContainer.className = 'pnlm-ui'; 152 container.appendChild(uiContainer); 153 154// Create container for renderer 155 var renderContainer = document.createElement('div'); 156 renderContainer.className = 'pnlm-render-container'; 157 container.appendChild(renderContainer); 158 var dragFix = document.createElement('div'); 159 dragFix.className = 'pnlm-dragfix'; 160 uiContainer.appendChild(dragFix); 161 162// Display about information on right click off 163// var aboutMsg = document.createElement('span'); 164// aboutMsg.className = 'pnlm-about-msg'; 165//==wpvr custom rextheme link==// 166// aboutMsg.innerHTML = '<a href="https://rextheme.com/docs/wpvr-360-panorama-and-virtual-tour-creator-for-wordpress/" target="_blank">Rextheme</a>'; 167//==wpvr custom rextheme link end==// 168// uiContainer.appendChild(aboutMsg); 169// dragFix.addEventListener('contextmenu', aboutMessage); 170 171// Create info display 172 var infoDisplay = {}; 173 174// Hot spot debug indicator 175 var hotSpotDebugIndicator = document.createElement('div'); 176 hotSpotDebugIndicator.className = 'pnlm-sprite pnlm-hot-spot-debug-indicator'; 177 uiContainer.appendChild(hotSpotDebugIndicator); 178 179// Panorama info 180 infoDisplay.container = document.createElement('div'); 181 infoDisplay.container.className = 'pnlm-panorama-info'; 182 infoDisplay.title = document.createElement('div'); 183 infoDisplay.title.className = 'pnlm-title-box'; 184 infoDisplay.container.appendChild(infoDisplay.title); 185 infoDisplay.author = document.createElement('div'); 186 infoDisplay.author.className = 'pnlm-author-box'; 187 infoDisplay.container.appendChild(infoDisplay.author); 188 uiContainer.appendChild(infoDisplay.container); 189 190// Load box 191 infoDisplay.load = {}; 192 infoDisplay.load.box = document.createElement('div'); 193 infoDisplay.load.box.className = 'pnlm-load-box'; 194 infoDisplay.load.boxp = document.createElement('p'); 195 infoDisplay.load.box.appendChild(infoDisplay.load.boxp); 196 infoDisplay.load.lbox = document.createElement('div'); 197 infoDisplay.load.lbox.className = 'pnlm-lbox'; 198 infoDisplay.load.lbox.innerHTML = '<div class="pnlm-loading"></div>'; 199 infoDisplay.load.box.appendChild(infoDisplay.load.lbox); 200 infoDisplay.load.lbar = document.createElement('div'); 201 infoDisplay.load.lbar.className = 'pnlm-lbar'; 202 infoDisplay.load.lbarFill = document.createElement('div'); 203 infoDisplay.load.lbarFill.className = 'pnlm-lbar-fill'; 204 infoDisplay.load.lbar.appendChild(infoDisplay.load.lbarFill); 205 infoDisplay.load.box.appendChild(infoDisplay.load.lbar); 206 infoDisplay.load.msg = document.createElement('p'); 207 infoDisplay.load.msg.className = 'pnlm-lmsg'; 208 infoDisplay.load.box.appendChild(infoDisplay.load.msg); 209 uiContainer.appendChild(infoDisplay.load.box); 210 211// Error message 212 infoDisplay.errorMsg = document.createElement('div'); 213 infoDisplay.errorMsg.className = 'pnlm-error-msg pnlm-info-box'; 214 uiContainer.appendChild(infoDisplay.errorMsg); 215 216// Create controls 217 var controls = {}; 218 controls.container = document.createElement('div');
219 controls.container.className = 'pnlm-controls-container'; 220 uiContainer.appendChild(controls.container); 221 222// Load button 223 controls.load = document.createElement('div'); 224 controls.load.className = 'pnlm-load-button'; 225 controls.load.addEventListener('click', function() { 226 processOptions(); 227 load(); 228 }); 229 uiContainer.appendChild(controls.load); 230 231// Zoom controls 232 controls.zoom = document.createElement('div'); 233 controls.zoom.className = 'pnlm-zoom-controls pnlm-controls'; 234 controls.zoomIn = document.createElement('div'); 235 controls.zoomIn.className = 'pnlm-zoom-in pnlm-sprite pnlm-control'; 236 controls.zoomIn.addEventListener('click', zoomIn); 237 controls.zoom.appendChild(controls.zoomIn); 238 controls.zoomOut = document.createElement('div'); 239 controls.zoomOut.className = 'pnlm-zoom-out pnlm-sprite pnlm-control'; 240 controls.zoomOut.addEventListener('click', zoomOut); 241 controls.zoom.appendChild(controls.zoomOut); 242 controls.container.appendChild(controls.zoom); 243 244// Fullscreen toggle 245 controls.fullscreen = document.createElement('div'); 246 controls.fullscreen.addEventListener('click', toggleFullscreen); 247 controls.fullscreen.className = 'pnlm-fullscreen-toggle-button pnlm-sprite pnlm-fullscreen-toggle-button-inactive pnlm-controls pnlm-control'; 248 if (document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled) 249 controls.container.appendChild(controls.fullscreen); 250 251// Device orientation toggle 252 controls.orientation = document.createElement('div'); 253 controls.orientation.addEventListener('click', function(e) { 254 if (orientation) 255 stopOrientation(); 256 else 257 startOrientation(); 258 }); 259 controls.orientation.addEventListener('mousedown', function(e) {e.stopPropagation();}); 260 controls.orientation.addEventListener('touchstart', function(e) {e.stopPropagation();}); 261 controls.orientation.addEventListener('pointerdown', function(e) {e.stopPropagation();}); 262 controls.orientation.className = 'pnlm-orientation-button pnlm-orientation-button-inactive pnlm-sprite pnlm-controls pnlm-control'; 263 var orientationSupport = false; 264 if (window.DeviceOrientationEvent && location.protocol == 'https:' && 265 navigator.userAgent.toLowerCase().indexOf('mobi') >= 0) { 266 // This user agent check is here because there's no way to check if a 267 // device has an inertia measurement unit. We used to be able to check if a 268 // DeviceOrientationEvent had non-null values, but with iOS 13 requiring a 269 // permission prompt to access such events, this is no longer possible. 270 controls.container.appendChild(controls.orientation); 271 orientationSupport = true; 272 } 273 274// Compass 275 var compass = document.createElement('div'); 276 compass.className = 'pnlm-compass pnlm-controls pnlm-control'; 277 uiContainer.appendChild(compass); 278 279// Load and process configuration 280 if (initialConfig.firstScene) { 281 // Activate first scene if specified in URL 282 mergeConfig(initialConfig.firstScene); 283 } else if (initialConfig.default && initialConfig.default.firstScene) { 284 // Activate first scene if specified in file 285 mergeConfig(initialConfig.default.firstScene); 286 } else { 287 mergeConfig(null); 288 } 289 processOptions(true); 290 291 /** 292 * Initializes viewer. 293 * @private 294 */ 295 function init() { 296 // Display an error for IE 9 as it doesn't work but also doesn't otherwise 297 // show an error (older versions don't work at all) 298 // Based on: http://stackoverflow.com/a/10965203 299 var div = document.createElement("div"); 300 div.innerHTML = "<!--[if lte IE 9]><i></i><![endif]-->"; 301 if (div.getElementsByTagName("i").length == 1) { 302 anError(); 303 return; 304 } 305 306 origHfov = config.hfov; 307 origPitch = config.pitch; 308 309 var i, p; 310 311 if (config.type == 'cubemap') { 312 panoImage = []; 313 for (i = 0; i < 6; i++) { 314 panoImage.push(new Image()); 315 panoImage[i].crossOrigin = config.crossOrigin; 316 } 317 infoDisplay.load.lbox.style.display = 'block'; 318 infoDisplay.load.lbar.style.display = 'none'; 319 } else if (config.type == 'multires') { 320 var c = JSON.parse(JSON.stringify(config.multiRes)); // Deep copy 321 // Avoid "undefined" in path, check (optional) multiRes.basePath, too 322 // Use only multiRes.basePath if it's an absolute URL 323 if (config.basePath && config.multiRes.basePath && 324 !(/^(?:[a-z]+:)?\/\//i.test(config.multiRes.basePath))) { 325 c.basePath = config.basePath + config.multiRes.basePath; 326 } else if (config.multiRes.basePath) { 327 c.basePath = config.multiRes.basePath; 328 } else if(config.basePath) { 329 c.basePath = config.basePath; 330 } 331 panoImage = c; 332 } else { 333 if (config.dynamic === true) { 334 panoImage = config.panorama; 335 } else { 336 if (config.panorama === undefined) { 337 anError(config.strings.noPanoramaError); 338 return; 339 } 340 panoImage = new Image(); 341 } 342 } 343 344 // Configure image loading 345 if (config.type == 'cubemap') { 346 // Quick loading counter for synchronous loading 347 var itemsToLoad = 6; 348 349 var onLoad = function() { 350 itemsToLoad--; 351 if (itemsToLoad === 0) { 352 onImageLoad(); 353 } 354 }; 355 356 var onError = function(e) { 357 var a = document.createElement('a'); 358 a.href = e.target.src; 359 a.textContent = a.href;
vendor: 7,842 bytes, lines 360-516
360 anError(config.strings.fileAccessError.replace('%s', a.outerHTML)); 361 }; 362 363 for (i = 0; i < panoImage.length; i++) { 364 p = config.cubeMap[i]; 365 if (p == "null") { // support partial cubemap image with explicitly empty faces 366 console.log('Will use background instead of missing cubemap face ' + i); 367 onLoad(); 368 } else { 369 if (config.basePath && !absoluteURL(p)) { 370 p = config.basePath + p; 371 } 372 panoImage[i].onload = onLoad; 373 panoImage[i].onerror = onError; 374 panoImage[i].src = sanitizeURL(p); 375 } 376 } 377 } else if (config.type == 'multires') { 378 onImageLoad(); 379 } else { 380 p = ''; 381 if (config.basePath) { 382 p = config.basePath; 383 } 384 385 if (config.dynamic !== true) { 386 // Still image 387 p = absoluteURL(config.panorama) ? config.panorama : p + config.panorama; 388 389 panoImage.onload = function() { 390 window.URL.revokeObjectURL(this.src); // Clean up 391 onImageLoad(); 392 }; 393 394 var xhr = new XMLHttpRequest(); 395 xhr.onloadend = function() { 396 if (xhr.status != 200) { 397 // Display error if image can't be loaded 398 var a = document.createElement('a'); 399 a.href = p; 400 a.textContent = a.href; 401 anError(config.strings.fileAccessError.replace('%s', a.outerHTML)); 402 } 403 var img = this.response; 404 parseGPanoXMP(img, p); 405 infoDisplay.load.msg.innerHTML = ''; 406 }; 407 xhr.onprogress = function(e) { 408 if (e.lengthComputable) { 409 // Display progress 410 var percent = e.loaded / e.total * 100; 411 infoDisplay.load.lbarFill.style.width = percent + '%'; 412 var unit, numerator, denominator; 413 if (e.total > 1e6) { 414 unit = 'MB'; 415 numerator = (e.loaded / 1e6).toFixed(2); 416 denominator = (e.total / 1e6).toFixed(2); 417 } else if (e.total > 1e3) { 418 unit = 'kB'; 419 numerator = (e.loaded / 1e3).toFixed(1); 420 denominator = (e.total / 1e3).toFixed(1); 421 } else { 422 unit = 'B'; 423 numerator = e.loaded; 424 denominator = e.total; 425 } 426 infoDisplay.load.msg.innerHTML = numerator + ' / ' + denominator + ' ' + unit; 427 } else { 428 // Display loading spinner 429 infoDisplay.load.lbox.style.display = 'block'; 430 infoDisplay.load.lbar.style.display = 'none'; 431 } 432 }; 433 try { 434 xhr.open('GET', p, true); 435 } catch (e) { 436 // Malformed URL 437 anError(config.strings.malformedURLError); 438 } 439 xhr.responseType = 'blob'; 440 xhr.setRequestHeader('Accept', 'image/*,*/*;q=0.9'); 441 xhr.withCredentials = config.crossOrigin === 'use-credentials'; 442 xhr.send(); 443 } 444 } 445 446 if (config.draggable) 447 uiContainer.classList.add('pnlm-grab'); 448 uiContainer.classList.remove('pnlm-grabbing'); 449 450 // Properly handle switching to dynamic scenes 451 update = config.dynamicUpdate === true; 452 if (config.dynamic && update) { 453 panoImage = config.panorama; 454 onImageLoad(); 455 } 456 } 457 458 /** 459 * Test if URL is absolute or relative. 460 * @private 461 * @param {string} url - URL to test 462 * @returns {boolean} True if absolute, else false 463 */ 464 function absoluteURL(url) { 465 // From http://stackoverflow.com/a/19709846 466 return new RegExp('^(?:[a-z]+:)?//', 'i').test(url) || url[0] == '/' || url.slice(0, 5) == 'blob:'; 467 } 468 469 /** 470 * Create renderer and initialize event listeners once image is loaded. 471 * @private 472 */ 473 function onImageLoad() { 474 if (!renderer) 475 renderer = new libpannellum.renderer(renderContainer); 476 477 // Only add event listeners once 478 if (!listenersAdded) { 479 listenersAdded = true; 480 dragFix.addEventListener('mousedown', onDocumentMouseDown, false); 481 document.addEventListener('mousemove', onDocumentMouseMove, false); 482 document.addEventListener('compasschange', onDocumentCompassChange, false); 483 document.addEventListener('mouseup', onDocumentMouseUp, false); 484 if (config.mouseZoom) { 485 uiContainer.addEventListener('mousewheel', onDocumentMouseWheel, false); 486 uiContainer.addEventListener('DOMMouseScroll', onDocumentMouseWheel, false); 487 } 488 if (config.doubleClickZoom) { 489 dragFix.addEventListener('dblclick', onDocumentDoubleClick, false); 490 } 491 container.addEventListener('mozfullscreenchange', onFullScreenChange, false); 492 container.addEventListener('webkitfullscreenchange', onFullScreenChange, false); 493 container.addEventListener('msfullscreenchange', onFullScreenChange, false); 494 container.addEventListener('fullscreenchange', onFullScreenChange, false); 495 window.addEventListener('resize', onDocumentResize, false); 496 window.addEventListener('orientationchange', onDocumentResize, false); 497 if (!config.disableKeyboardCtrl) { 498 container.addEventListener('keydown', onDocumentKeyPress, false); 499 container.addEventListener('keyup', onDocumentKeyUp, false); 500 container.addEventListener('blur', clearKeys, false); 501 } 502 document.addEventListener('mouseleave', onDocumentMouseUp, false); 503 if (document.documentElement.style.pointerAction === '' && 504 document.documentElement.style.touchAction === '') { 505 dragFix.addEventListener('pointerdown', onDocumentPointerDown, false); 506 dragFix.addEventListener('pointermove', onDocumentPointerMove, false); 507 dragFix.addEventListener('pointerup', onDocumentPointerUp, false); 508 dragFix.addEventListener('pointerleave', onDocumentPointerUp, false); 509 } else { 510 dragFix.addEventListener('touchstart', onDocumentTouchStart, false); 511 dragFix.addEventListener('touchmove', onDocumentTouchMove, false); 512 dragFix.addEventListener('touchend', onDocumentTouchEnd, false); 513 } 514 515 // Deal with MS pointer events 516 if (window.navigator.pointerEnabled)
517 container.style.touchAction = 'none'; 518 } 519 520 renderInit(); 521 setHfov(config.hfov); // possibly adapt hfov after configuration and canvas is complete; prevents empty space on top or bottom by zomming out too much 522 setTimeout(function(){isTimedOut = true;}, 500); 523 } 524 525 /** 526 * Parses Google Photo Sphere XMP Metadata. 527 * https://developers.google.com/photo-sphere/metadata/ 528 * @private 529 * @param {Image} image - Image to read XMP metadata from. 530 */ 531 function parseGPanoXMP(image, url) { 532 var reader = new FileReader(); 533 reader.addEventListener('loadend', function() { 534 var img = reader.result; 535 536 // This awful browser specific test exists because iOS 8 does not work 537 // with non-progressive encoded JPEGs. 538 if (navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad).* os 8_/)) { 539 var flagIndex = img.indexOf('\xff\xc2'); 540 if (flagIndex < 0 || flagIndex > 65536) 541 anError(config.strings.iOS8WebGLError); 542 } 543 544 var start = img.indexOf('<x:xmpmeta'); 545 if (start > -1 && config.ignoreGPanoXMP !== true) { 546 var xmpData = img.substring(start, img.indexOf('</x:xmpmeta>') + 12); 547 548 // Extract the requested tag from the XMP data 549 var getTag = function(tag) { 550 var result; 551 if (xmpData.indexOf(tag + '="') >= 0) { 552 result = xmpData.substring(xmpData.indexOf(tag + '="') + tag.length + 2); 553 result = result.substring(0, result.indexOf('"')); 554 } else if (xmpData.indexOf(tag + '>') >= 0) { 555 result = xmpData.substring(xmpData.indexOf(tag + '>') + tag.length + 1); 556 result = result.substring(0, result.indexOf('<')); 557 } 558 if (result !== undefined) { 559 return Number(result); 560 } 561 return null; 562 }; 563 564 // Relevant XMP data 565 var xmp = { 566 fullWidth: getTag('GPano:FullPanoWidthPixels'), 567 croppedWidth: getTag('GPano:CroppedAreaImageWidthPixels'), 568 fullHeight: getTag('GPano:FullPanoHeightPixels'), 569 croppedHeight: getTag('GPano:CroppedAreaImageHeightPixels'), 570 topPixels: getTag('GPano:CroppedAreaTopPixels'), 571 heading: getTag('GPano:PoseHeadingDegrees'), 572 horizonPitch: getTag('GPano:PosePitchDegrees'), 573 horizonRoll: getTag('GPano:PoseRollDegrees') 574 }; 575 576 if (xmp.fullWidth !== null && xmp.croppedWidth !== null && 577 xmp.fullHeight !== null && xmp.croppedHeight !== null && 578 xmp.topPixels !== null) { 579 580 // Set up viewer using GPano XMP data 581 if (specifiedPhotoSphereExcludes.indexOf('haov') < 0) 582 config.haov = xmp.croppedWidth / xmp.fullWidth * 360; 583 if (specifiedPhotoSphereExcludes.indexOf('vaov') < 0) 584 config.vaov = xmp.croppedHeight / xmp.fullHeight * 180; 585 if (specifiedPhotoSphereExcludes.indexOf('vOffset') < 0) 586 config.vOffset = ((xmp.topPixels + xmp.croppedHeight / 2) / xmp.fullHeight - 0.5) * -180; 587 if (xmp.heading !== null && specifiedPhotoSphereExcludes.indexOf('northOffset') < 0) { 588 // TODO: make sure this works correctly for partial panoramas 589 config.northOffset = xmp.heading; 590 if (config.compass !== false) { 591 config.compass = true; 592 } 593 } 594 if (xmp.horizonPitch !== null && xmp.horizonRoll !== null) { 595 if (specifiedPhotoSphereExcludes.indexOf('horizonPitch') < 0) 596 config.horizonPitch = xmp.horizonPitch; 597 if (specifiedPhotoSphereExcludes.indexOf('horizonRoll') < 0) 598 config.horizonRoll = xmp.horizonRoll; 599 } 600 601 // TODO: add support for initial view settings 602 } 603 } 604 605 // Load panorama 606 panoImage.src = window.URL.createObjectURL(image); 607 panoImage.onerror = function() { 608 // If the image fails to load, we check the Content Security Policy 609 // headers and see if they block loading images as blobs. If they 610 // do, we load the image directly from the URL. While this should 611 // allow the image to load, it does prevent parsing of XMP data. 612 function getCspHeaders() { 613 if (!window.fetch) 614 return null; 615 return window.fetch(document.location.href) 616 .then(function(resp){ 617 return resp.headers.get('Content-Security-Policy'); 618 }); 619 } 620 getCspHeaders().then(function(cspHeaders) { 621 if (cspHeaders) { 622 var invalidImgSource = cspHeaders.split(";").find(function(p) { 623 var matchstring = p.match(/img-src(.*)/); 624 if (matchstring) { 625 return !matchstring[1].includes("blob"); 626 } 627 }); 628 if (invalidImgSource) { 629 console.log('CSP blocks blobs; reverting to URL.'); 630 panoImage.crossOrigin = config.crossOrigin; 631 panoImage.src = url; 632 } 633 } 634 }); 635 } 636 }); 637 if (reader.readAsBinaryString !== undefined) 638 reader.readAsBinaryString(image); 639 else 640 reader.readAsText(image); 641 } 642 643 /**
644 * Displays an error message. 645 * @private 646 * @param {string} errorMsg - Error message to display. If not specified, a 647 * generic WebGL error is displayed. 648 */ 649 function anError(errorMsg) { 650 if (errorMsg === undefined) 651 errorMsg = config.strings.genericWebGLError; 652 infoDisplay.errorMsg.innerHTML = '<p>' + errorMsg + '</p>'; 653 controls.load.style.display = 'none'; 654 infoDisplay.load.box.style.display = 'none'; 655 infoDisplay.errorMsg.style.display = 'table'; 656 error = true; 657 loaded = undefined; 658 renderContainer.style.display = 'none'; 659 fireEvent('error', errorMsg); 660 } 661 662 /** 663 * Hides error message display. 664 * @private 665 */ 666 function clearError() { 667 if (error) { 668 infoDisplay.load.box.style.display = 'none'; 669 infoDisplay.errorMsg.style.display = 'none'; 670 error = false; 671 renderContainer.style.display = 'block'; 672 fireEvent('errorcleared'); 673 } 674 } 675 676 /** 677 * Displays about message. 678 * @private 679 * @param {MouseEvent} event - Right click location 680 */ 681 function aboutMessage(event) { 682 var pos = mousePosition(event); 683 aboutMsg.style.left = pos.x + 'px'; 684 aboutMsg.style.top = pos.y + 'px'; 685 clearTimeout(aboutMessage.t1); 686 clearTimeout(aboutMessage.t2); 687 aboutMsg.style.display = 'block'; 688 aboutMsg.style.opacity = 1; 689 aboutMessage.t1 = setTimeout(function() {aboutMsg.style.opacity = 0;}, 2000); 690 aboutMessage.t2 = setTimeout(function() {aboutMsg.style.display = 'none';}, 2500); 691 event.preventDefault(); 692 } 693 694 /** 695 * Calculate mouse position relative to top left of viewer container. 696 * @private 697 * @param {MouseEvent} event - Mouse event to use in calculation 698 * @returns {Object} Calculated X and Y coordinates 699 */ 700 function mousePosition(event) { 701 var bounds = container.getBoundingClientRect(); 702 var pos = {}; 703 // pageX / pageY needed for iOS 704 pos.x = (event.clientX || event.pageX) - bounds.left; 705 pos.y = (event.clientY || event.pageY) - bounds.top; 706 return pos; 707 } 708 709 /** 710 * Event handler for mouse clicks. Initializes panning. Prints center and click 711 * location coordinates when hot spot debugging is enabled. 712 * @private 713 * @param {MouseEvent} event - Document mouse down event. 714 */ 715 function onDocumentMouseDown(event) { 716 // Override default action 717 event.preventDefault(); 718 // But not all of it 719 container.focus(); 720 721 // Only do something if the panorama is loaded 722 if (!loaded || !config.draggable) { 723 return; 724 } 725 726 // Calculate mouse position relative to top left of viewer container 727 var pos = mousePosition(event); 728 729 // Log pitch / yaw of mouse click when debugging / placing hot spots 730 if (config.hotSpotDebug) { 731 var coords = mouseEventToCoords(event); 732 console.log('Pitch: ' + coords[0] + ', Yaw: ' + coords[1] + ', Center Pitch: ' + 733 config.pitch + ', Center Yaw: ' + config.yaw + ', HFOV: ' + config.hfov); 734 } 735 736 // Turn off auto-rotation if enabled 737 stopAnimation(); 738 739 stopOrientation(); 740 config.roll = 0; 741 742 speed.hfov = 0; 743 744 isUserInteracting = true; 745 latestInteraction = Date.now(); 746 747 onPointerDownPointerX = pos.x; 748 onPointerDownPointerY = pos.y; 749 750 onPointerDownYaw = config.yaw; 751 onPointerDownPitch = config.pitch; 752 753 uiContainer.classList.add('pnlm-grabbing'); 754 uiContainer.classList.remove('pnlm-grab'); 755 756 fireEvent('mousedown', event); 757 animateInit(); 758 } 759 760 /** 761 * Event handler for double clicks. Zooms in at clicked location 762 * @private 763 * @param {MouseEvent} event - Document mouse down event. 764 */ 765 function onDocumentDoubleClick(event) { 766 if (config.minHfov === config.hfov) { 767 _this.setHfov(origHfov, 1000); 768 } else { 769 var coords = mouseEventToCoords(event); 770 _this.lookAt(coords[0], coords[1], config.minHfov, 1000); 771 } 772 } 773 774 /** 775 * Calculate panorama pitch and yaw from location of mouse event. 776 * @private 777 * @param {MouseEvent} event - Document mouse down event. 778 * @returns {number[]} [pitch, yaw] 779 */ 780 function mouseEventToCoords(event) { 781 var pos = mousePosition(event); 782 var canvas = renderer.getCanvas(); 783 var canvasWidth = canvas.clientWidth, 784 canvasHeight = canvas.clientHeight; 785 var x = pos.x / canvasWidth * 2 - 1; 786 var y = (1 - pos.y / canvasHeight * 2) * canvasHeight / canvasWidth; 787 var focal = 1 / Math.tan(config.hfov * Math.PI / 360); 788 var s = Math.sin(config.pitch * Math.PI / 180); 789 var c = Math.cos(config.pitch * Math.PI / 180); 790 var a = focal * c - y * s; 791 var root = Math.sqrt(x*x + a*a); 792 var pitch = Math.atan((y * c + focal * s) / root) * 180 / Math.PI; 793 var yaw = Math.atan2(x / root, a / root) * 180 / Math.PI + config.yaw; 794 if (yaw < -180) 795 yaw += 360; 796 if (yaw > 180) 797 yaw -= 360; 798 return [pitch, yaw]; 799 } 800 801 function onDocumentCompassChange(event) { 802 803 } 804 805 /** 806 * Event handler for mouse moves. Pans center of view. 807 * @private 808 * @param {MouseEvent} event - Document mouse move event. 809 */ 810 function onDocumentMouseMove(event) { 811 if (isUserInteracting && loaded) { 812 latestInteraction = Date.now(); 813 var canvas = renderer.getCanvas(); 814 var canvasWidth = canvas.clientWidth, 815 canvasHeight = canvas.clientHeight; 816 var pos = mousePosition(event); 817 //TODO: This still isn't quite right 818 var yaw = ((Math.atan(onPointerDownPointerX / canvasWidth * 2 - 1) - Math.atan(pos.x / canvasWidth * 2 - 1)) * 180 / Math.PI * config.hfov / 90) + onPointerDownYaw; 819 speed.yaw = (yaw - config.yaw) % 360 * 0.2; 820 config.yaw = yaw; 821 822 var vfov = 2 * Math.atan(Math.tan(config.hfov/360*Math.PI) * canvasHeight / canvasWidth) * 180 / Math.PI; 823 824 var pitch = ((Math.atan(pos.y / canvasHeight * 2 - 1) - Math.atan(onPointerDownPointerY / canvasHeight * 2 - 1)) * 180 / Math.PI * vfov / 90) + onPointerDownPitch; 825 speed.pitch = (pitch - config.pitch) * 0.2; 826 config.pitch = pitch; 827 828 var mirrorData = { 829 pitch: pitch, 830 yaw: yaw 831 } 832 fireEvent('mousemove', mirrorData); 833 834 } 835 } 836 837 /** 838 * Event handler for mouse up events. Stops panning. 839 * @private 840 */ 841 function onDocumentMouseUp(event) { 842 if (!isUserInteracting) { 843 return; 844 } 845 isUserInteracting = false;
vendor: 4,780 bytes, lines 846-962
846 if (Date.now() - latestInteraction > 15) { 847 // Prevents jump when user rapidly moves mouse, stops, and then 848 // releases the mouse button 849 speed.pitch = speed.yaw = 0; 850 } 851 uiContainer.classList.add('pnlm-grab'); 852 uiContainer.classList.remove('pnlm-grabbing'); 853 latestInteraction = Date.now(); 854 855 fireEvent('mouseup', event); 856 } 857 858 /** 859 * Event handler for touches. Initializes panning if one touch or zooming if 860 * two touches. 861 * @private 862 * @param {TouchEvent} event - Document touch start event. 863 */ 864 function onDocumentTouchStart(event) { 865 // Only do something if the panorama is loaded 866 if (!loaded || !config.draggable) { 867 return; 868 } 869 870 // Turn off auto-rotation if enabled 871 stopAnimation(); 872 873 stopOrientation(); 874 config.roll = 0; 875 876 speed.hfov = 0; 877 878 // Calculate touch position relative to top left of viewer container 879 var pos0 = mousePosition(event.targetTouches[0]); 880 881 onPointerDownPointerX = pos0.x; 882 onPointerDownPointerY = pos0.y; 883 884 if (event.targetTouches.length == 2) { 885 // Down pointer is the center of the two fingers 886 var pos1 = mousePosition(event.targetTouches[1]); 887 onPointerDownPointerX += (pos1.x - pos0.x) * 0.5; 888 onPointerDownPointerY += (pos1.y - pos0.y) * 0.5; 889 onPointerDownPointerDist = Math.sqrt((pos0.x - pos1.x) * (pos0.x - pos1.x) + 890 (pos0.y - pos1.y) * (pos0.y - pos1.y)); 891 } 892 isUserInteracting = true; 893 latestInteraction = Date.now(); 894 895 onPointerDownYaw = config.yaw; 896 onPointerDownPitch = config.pitch; 897 898 fireEvent('touchstart', event); 899 animateInit(); 900 } 901 902 /** 903 * Event handler for touch movements. Pans center of view if one touch or 904 * adjusts zoom if two touches. 905 * @private 906 * @param {TouchEvent} event - Document touch move event. 907 */ 908 function onDocumentTouchMove(event) { 909 if (!config.draggable) { 910 return; 911 } 912 913 // Override default action 914 event.preventDefault(); 915 if (loaded) { 916 latestInteraction = Date.now(); 917 } 918 if (isUserInteracting && loaded) { 919 var pos0 = mousePosition(event.targetTouches[0]); 920 var clientX = pos0.x; 921 var clientY = pos0.y; 922 923 if (event.targetTouches.length == 2 && onPointerDownPointerDist != -1) { 924 var pos1 = mousePosition(event.targetTouches[1]); 925 clientX += (pos1.x - pos0.x) * 0.5; 926 clientY += (pos1.y - pos0.y) * 0.5; 927 var clientDist = Math.sqrt((pos0.x - pos1.x) * (pos0.x - pos1.x) + 928 (pos0.y - pos1.y) * (pos0.y - pos1.y)); 929 setHfov(config.hfov + (onPointerDownPointerDist - clientDist) * 0.1); 930 onPointerDownPointerDist = clientDist; 931 } 932 933 // The smaller the config.hfov value (the more zoomed-in the user is), the faster 934 // yaw/pitch are perceived to change on one-finger touchmove (panning) events and vice versa. 935 // To improve usability at both small and large zoom levels (config.hfov values) 936 // we introduce a dynamic pan speed coefficient. 937 // 938 // Currently this seems to *roughly* keep initial drag/pan start position close to 939 // the user's finger while panning regardless of zoom level / config.hfov value. 940 var touchmovePanSpeedCoeff = (config.hfov / 360) * config.touchPanSpeedCoeffFactor; 941 942 var yaw = (onPointerDownPointerX - clientX) * touchmovePanSpeedCoeff + onPointerDownYaw; 943 speed.yaw = (yaw - config.yaw) % 360 * 0.2; 944 config.yaw = yaw; 945 946 var pitch = (clientY - onPointerDownPointerY) * touchmovePanSpeedCoeff + onPointerDownPitch; 947 speed.pitch = (pitch - config.pitch) * 0.2; 948 config.pitch = pitch; 949 var mirrorData = { 950 pitch: pitch, 951 yaw: yaw 952 } 953 fireEvent('touchmove', mirrorData); 954 } 955 } 956 957 /** 958 * Event handler for end of touches. Stops panning and/or zooming. 959 * @private 960 */ 961 function onDocumentTouchEnd() { 962 isUserInteracting = false;
963 if (Date.now() - latestInteraction > 150) { 964 speed.pitch = speed.yaw = 0; 965 } 966 onPointerDownPointerDist = -1; 967 latestInteraction = Date.now(); 968 969 fireEvent('touchend', event); 970 } 971 972 var pointerIDs = [], 973 pointerCoordinates = []; 974 /** 975 * Event handler for touch starts in IE / Edge. 976 * @private 977 * @param {PointerEvent} event - Document pointer down event. 978 */ 979 function onDocumentPointerDown(event) { 980 if (event.pointerType == 'touch') { 981 // Only do something if the panorama is loaded 982 if (!loaded || !config.draggable) 983 return; 984 pointerIDs.push(event.pointerId); 985 pointerCoordinates.push({clientX: event.clientX, clientY: event.clientY}); 986 event.targetTouches = pointerCoordinates; 987 onDocumentTouchStart(event); 988 event.preventDefault(); 989 } 990 } 991 992 /** 993 * Event handler for touch moves in IE / Edge. 994 * @private 995 * @param {PointerEvent} event - Document pointer move event. 996 */ 997 function onDocumentPointerMove(event) { 998 if (event.pointerType == 'touch') { 999 if (!config.draggable) 1000 return; 1001 for (var i = 0; i < pointerIDs.length; i++) { 1002 if (event.pointerId == pointerIDs[i]) { 1003 pointerCoordinates[i].clientX = event.clientX; 1004 pointerCoordinates[i].clientY = event.clientY; 1005 event.targetTouches = pointerCoordinates; 1006 onDocumentTouchMove(event); 1007 event.preventDefault(); 1008 return; 1009 } 1010 } 1011 } 1012 } 1013 1014 /** 1015 * Event handler for touch ends in IE / Edge. 1016 * @private 1017 * @param {PointerEvent} event - Document pointer up event. 1018 */ 1019 function onDocumentPointerUp(event) { 1020 if (event.pointerType == 'touch') { 1021 var defined = false; 1022 for (var i = 0; i < pointerIDs.length; i++) { 1023 if (event.pointerId == pointerIDs[i]) 1024 pointerIDs[i] = undefined; 1025 if (pointerIDs[i]) 1026 defined = true; 1027 } 1028 if (!defined) { 1029 pointerIDs = []; 1030 pointerCoordinates = []; 1031 onDocumentTouchEnd(); 1032 } 1033 event.preventDefault(); 1034 } 1035 } 1036 1037 /** 1038 * Event handler for mouse wheel. Changes zoom. 1039 * @private 1040 * @param {WheelEvent} event - Document mouse wheel event. 1041 */ 1042 function onDocumentMouseWheel(event) { 1043 // Only do something if the panorama is loaded and mouse wheel zoom is enabled 1044 if (!loaded || (config.mouseZoom == 'fullscreenonly' && !fullscreenActive)) { 1045 return; 1046 } 1047 1048 event.preventDefault(); 1049 1050 // Turn off auto-rotation if enabled 1051 stopAnimation(); 1052 latestInteraction = Date.now(); 1053 1054 if (event.wheelDeltaY) { 1055 // WebKit 1056 setHfov(config.hfov - event.wheelDeltaY * 0.05); 1057 speed.hfov = event.wheelDelta < 0 ? 1 : -1; 1058 } else if (event.wheelDelta) { 1059 // Opera / Explorer 9 1060 setHfov(config.hfov - event.wheelDelta * 0.05); 1061 speed.hfov = event.wheelDelta < 0 ? 1 : -1; 1062 } else if (event.detail) { 1063 // Firefox 1064 setHfov(config.hfov + event.detail * 1.5); 1065 speed.hfov = event.detail > 0 ? 1 : -1; 1066 } 1067 animateInit(); 1068 } 1069 1070 /** 1071 * Event handler for key presses. Updates list of currently pressed keys. 1072 * @private 1073 * @param {KeyboardEvent} event - Document key press event. 1074 */ 1075 function onDocumentKeyPress(event) { 1076 // Turn off auto-rotation if enabled 1077 stopAnimation(); 1078 latestInteraction = Date.now(); 1079 1080 stopOrientation(); 1081 config.roll = 0; 1082 1083 // Record key pressed 1084 var keynumber = event.which || event.keycode; 1085 1086 // Override default action for keys that are used 1087 if (config.capturedKeyNumbers.indexOf(keynumber) < 0) 1088 return; 1089 event.preventDefault(); 1090 1091 // If escape key is pressed 1092 if (keynumber == 27) { 1093 // If in fullscreen mode 1094 if (fullscreenActive) { 1095 toggleFullscreen(); 1096 } 1097 } else { 1098 // Change key 1099 changeKey(keynumber, true); 1100 } 1101 } 1102 1103 /** 1104 * Clears list of currently pressed keys. 1105 * @private 1106 */ 1107 function clearKeys() { 1108 for (var i = 0; i < 10; i++) { 1109 keysDown[i] = false;
vendor: 6,327 bytes, lines 1110-1287
1110 } 1111 } 1112 1113 /** 1114 * Event handler for key releases. Updates list of currently pressed keys. 1115 * @private 1116 * @param {KeyboardEvent} event - Document key up event. 1117 */ 1118 function onDocumentKeyUp(event) { 1119 // Record key pressed 1120 var keynumber = event.which || event.keycode; 1121 1122 // Override default action for keys that are used 1123 if (config.capturedKeyNumbers.indexOf(keynumber) < 0) 1124 return; 1125 event.preventDefault(); 1126 1127 // Change key 1128 changeKey(keynumber, false); 1129 } 1130 1131 /** 1132 * Updates list of currently pressed keys. 1133 * @private 1134 * @param {number} keynumber - Key number. 1135 * @param {boolean} value - Whether or not key is pressed. 1136 */ 1137 function changeKey(keynumber, value) { 1138 var keyChanged = false; 1139 switch(keynumber) { 1140 // If minus key is released 1141 case 109: case 189: case 17: case 173: 1142 if (keysDown[0] != value) { keyChanged = true; } 1143 keysDown[0] = value; break; 1144 1145 // If plus key is released 1146 case 107: case 187: case 16: case 61: 1147 if (keysDown[1] != value) { keyChanged = true; } 1148 keysDown[1] = value; break; 1149 1150 // If up arrow is released 1151 case 38: 1152 if (keysDown[2] != value) { keyChanged = true; } 1153 keysDown[2] = value; break; 1154 1155 // If "w" is released 1156 case 87: 1157 if (keysDown[6] != value) { keyChanged = true; } 1158 keysDown[6] = value; break; 1159 1160 // If down arrow is released 1161 case 40: 1162 if (keysDown[3] != value) { keyChanged = true; } 1163 keysDown[3] = value; break; 1164 1165 // If "s" is released 1166 case 83: 1167 if (keysDown[7] != value) { keyChanged = true; } 1168 keysDown[7] = value; break; 1169 1170 // If left arrow is released 1171 case 37: 1172 if (keysDown[4] != value) { keyChanged = true; } 1173 keysDown[4] = value; break; 1174 1175 // If "a" is released 1176 case 65: 1177 if (keysDown[8] != value) { keyChanged = true; } 1178 keysDown[8] = value; break; 1179 1180 // If right arrow is released 1181 case 39: 1182 if (keysDown[5] != value) { keyChanged = true; } 1183 keysDown[5] = value; break; 1184 1185 // If "d" is released 1186 case 68: 1187 if (keysDown[9] != value) { keyChanged = true; } 1188 keysDown[9] = value; 1189 } 1190 1191 if (keyChanged && value) { 1192 if (typeof performance !== 'undefined' && performance.now()) { 1193 prevTime = performance.now(); 1194 } else { 1195 prevTime = Date.now(); 1196 } 1197 animateInit(); 1198 } 1199 } 1200 1201 /** 1202 * Pans and/or zooms panorama based on currently pressed keys. Also handles 1203 * panorama "inertia" and auto rotation. 1204 * @private 1205 */ 1206 function keyRepeat() { 1207 // Only do something if the panorama is loaded 1208 if (!loaded) { 1209 return; 1210 } 1211 1212 var isKeyDown = false; 1213 1214 var prevPitch = config.pitch; 1215 var prevYaw = config.yaw; 1216 var prevZoom = config.hfov; 1217 1218 var newTime; 1219 if (typeof performance !== 'undefined' && performance.now()) { 1220 newTime = performance.now(); 1221 } else { 1222 newTime = Date.now(); 1223 } 1224 if (prevTime === undefined) { 1225 prevTime = newTime; 1226 } 1227 var diff = (newTime - prevTime) * config.hfov / 1700; 1228 diff = Math.min(diff, 1.0); 1229 1230 // If minus key is down 1231 if (keysDown[0] && config.keyboardZoom === true) { 1232 setHfov(config.hfov + (speed.hfov * 0.8 + 0.5) * diff); 1233 isKeyDown = true; 1234 } 1235 1236 // If plus key is down 1237 if (keysDown[1] && config.keyboardZoom === true) { 1238 setHfov(config.hfov + (speed.hfov * 0.8 - 0.2) * diff); 1239 isKeyDown = true; 1240 } 1241 1242 // If up arrow or "w" is down 1243 if (keysDown[2] || keysDown[6]) { 1244 // Pan up 1245 config.pitch += (speed.pitch * 0.8 + 0.2) * diff; 1246 isKeyDown = true; 1247 } 1248 1249 // If down arrow or "s" is down 1250 if (keysDown[3] || keysDown[7]) { 1251 // Pan down 1252 config.pitch += (speed.pitch * 0.8 - 0.2) * diff; 1253 isKeyDown = true; 1254 } 1255 1256 // If left arrow or "a" is down 1257 if (keysDown[4] || keysDown[8]) { 1258 // Pan left 1259 config.yaw += (speed.yaw * 0.8 - 0.2) * diff; 1260 isKeyDown = true; 1261 } 1262 1263 // If right arrow or "d" is down 1264 if (keysDown[5] || keysDown[9]) { 1265 // Pan right 1266 config.yaw += (speed.yaw * 0.8 + 0.2) * diff; 1267 isKeyDown = true; 1268 } 1269 1270 if (isKeyDown) 1271 latestInteraction = Date.now(); 1272 1273 // If auto-rotate 1274 if (config.autoRotate) { 1275 // Pan 1276 if (newTime - prevTime > 0.001) { 1277 var timeDiff = (newTime - prevTime) / 1000; 1278 var yawDiff = (speed.yaw / timeDiff * diff - config.autoRotate * 0.2) * timeDiff; 1279 yawDiff = (-config.autoRotate > 0 ? 1 : -1) * Math.min(Math.abs(config.autoRotate * timeDiff), Math.abs(yawDiff)); 1280 config.yaw += yawDiff; 1281 } 1282 1283 // Deal with stopping auto rotation after a set delay 1284 if (config.autoRotateStopDelay) { 1285 config.autoRotateStopDelay -= newTime - prevTime; 1286 if (config.autoRotateStopDelay <= 0) { 1287 config.autoRotateStopDelay = false;
1288 autoRotateSpeed = config.autoRotate; 1289 config.autoRotate = 0; 1290 } 1291 } 1292 } 1293 1294 // Animated moves 1295 if (animatedMove.pitch) { 1296 animateMove('pitch'); 1297 prevPitch = config.pitch; 1298 } 1299 if (animatedMove.yaw) { 1300 animateMove('yaw'); 1301 prevYaw = config.yaw; 1302 } 1303 if (animatedMove.hfov) { 1304 animateMove('hfov'); 1305 prevZoom = config.hfov; 1306 } 1307 1308 // "Inertia" 1309 if (diff > 0 && !config.autoRotate) { 1310 // "Friction" 1311 var slowDownFactor = 1 - config.friction; 1312 1313 // Yaw 1314 if (!keysDown[4] && !keysDown[5] && !keysDown[8] && !keysDown[9] && !animatedMove.yaw) { 1315 config.yaw += speed.yaw * diff * slowDownFactor; 1316 } 1317 // Pitch 1318 if (!keysDown[2] && !keysDown[3] && !keysDown[6] && !keysDown[7] && !animatedMove.pitch) { 1319 config.pitch += speed.pitch * diff * slowDownFactor; 1320 } 1321 // Zoom 1322 if (!keysDown[0] && !keysDown[1] && !animatedMove.hfov) { 1323 setHfov(config.hfov + speed.hfov * diff * slowDownFactor); 1324 } 1325 } 1326 1327 prevTime = newTime; 1328 if (diff > 0) { 1329 speed.yaw = speed.yaw * 0.8 + (config.yaw - prevYaw) / diff * 0.2; 1330 speed.pitch = speed.pitch * 0.8 + (config.pitch - prevPitch) / diff * 0.2; 1331 speed.hfov = speed.hfov * 0.8 + (config.hfov - prevZoom) / diff * 0.2; 1332 1333 // Limit speed 1334 var maxSpeed = config.autoRotate ? Math.abs(config.autoRotate) : 5; 1335 speed.yaw = Math.min(maxSpeed, Math.max(speed.yaw, -maxSpeed)); 1336 speed.pitch = Math.min(maxSpeed, Math.max(speed.pitch, -maxSpeed)); 1337 speed.hfov = Math.min(maxSpeed, Math.max(speed.hfov, -maxSpeed)); 1338 } 1339 1340 // Stop movement if opposite controls are pressed 1341 if (keysDown[0] && keysDown[1]) { 1342 speed.hfov = 0; 1343 } 1344 if ((keysDown[2] || keysDown[6]) && (keysDown[3] || keysDown[7])) { 1345 speed.pitch = 0; 1346 } 1347 if ((keysDown[4] || keysDown[8]) && (keysDown[5] || keysDown[9])) { 1348 speed.yaw = 0; 1349 } 1350 } 1351 1352 /** 1353 * Animates moves. 1354 * @param {string} axis - Axis to animate 1355 * @private 1356 */ 1357 function animateMove(axis) { 1358 var t = animatedMove[axis]; 1359 var normTime = Math.min(1, Math.max((Date.now() - t.startTime) / 1000 / (t.duration / 1000), 0)); 1360 var result = t.startPosition + config.animationTimingFunction(normTime) * (t.endPosition - t.startPosition); 1361 if ((t.endPosition > t.startPosition && result >= t.endPosition) || 1362 (t.endPosition < t.startPosition && result <= t.endPosition) || 1363 t.endPosition === t.startPosition) { 1364 result = t.endPosition; 1365 speed[axis] = 0; 1366 delete animatedMove[axis]; 1367 } 1368 config[axis] = result; 1369 } 1370 1371 /** 1372 * @param {number} t - Normalized time in animation 1373 * @return {number} Position in animation 1374 * @private 1375 */ 1376 function timingFunction(t) { 1377 // easeInOutQuad from https://gist.github.com/gre/1650294 1378 return t < 0.5 ? 2*t*t : -1+(4-2*t)*t; 1379 } 1380 1381 /** 1382 * Event handler for document resizes. Updates viewer size and rerenders view. 1383 * @private 1384 */ 1385 function onDocumentResize() { 1386 // Resize panorama renderer (moved to onFullScreenChange) 1387 //renderer.resize(); 1388 //animateInit(); 1389 1390 // Kludge to deal with WebKit regression: https://bugs.webkit.org/show_bug.cgi?id=93525 1391 onFullScreenChange('resize'); 1392 } 1393 1394 /** 1395 * Initializes animation. 1396 * @private 1397 */ 1398 function animateInit() { 1399 if (animating) { 1400 return; 1401 } 1402 animating = true; 1403 animate(); 1404 } 1405 1406 /** 1407 * Animates view, using requestAnimationFrame to trigger rendering. 1408 * @private 1409 */ 1410 function animate() { 1411 if (destroyed) { 1412 return; 1413 } 1414 1415 render(); 1416 if (autoRotateStart) 1417 clearTimeout(autoRotateStart); 1418 if (isUserInteracting || orientation === true) { 1419 requestAnimationFrame(animate); 1420 } else if (keysDown[0] || keysDown[1] || keysDown[2] || keysDown[3] || 1421 keysDown[4] || keysDown[5] || keysDown[6] || keysDown[7] || 1422 keysDown[8] || keysDown[9] || config.autoRotate || 1423 animatedMove.pitch || animatedMove.yaw || animatedMove.hfov || 1424 Math.abs(speed.yaw) > 0.01 || Math.abs(speed.pitch) > 0.01 || 1425 Math.abs(speed.hfov) > 0.01) { 1426 1427 keyRepeat(); 1428 if (config.autoRotateInactivityDelay >= 0 && autoRotateSpeed && 1429 Date.now() - latestInteraction > config.autoRotateInactivityDelay && 1430 !config.autoRotate) { 1431 config.autoRotate = autoRotateSpeed; 1432 _this.lookAt(origPitch, undefined, origHfov, 3000); 1433 } 1434 requestAnimationFrame(animate); 1435 } else if (renderer && (renderer.isLoading() || (config.dynamic === true && update))) { 1436 requestAnimationFrame(animate); 1437 } else { 1438 fireEvent('animatefinished', {pitch: _this.getPitch(), yaw: _this.getYaw(), hfov: _this.getHfov()}); 1439 animating = false;
vendor: 14,108 bytes, lines 1440-1763
1440 prevTime = undefined; 1441 var autoRotateStartTime = config.autoRotateInactivityDelay - 1442 (Date.now() - latestInteraction); 1443 if (autoRotateStartTime > 0) { 1444 autoRotateStart = setTimeout(function() { 1445 config.autoRotate = autoRotateSpeed; 1446 _this.lookAt(origPitch, undefined, origHfov, 3000); 1447 animateInit(); 1448 }, autoRotateStartTime); 1449 } else if (config.autoRotateInactivityDelay >= 0 && autoRotateSpeed) { 1450 config.autoRotate = autoRotateSpeed; 1451 _this.lookAt(origPitch, undefined, origHfov, 3000); 1452 animateInit(); 1453 } 1454 } 1455 } 1456 1457 /** 1458 * Renders panorama view. 1459 * @private 1460 */ 1461 function render() { 1462 var tmpyaw; 1463 1464 if (loaded) { 1465 var canvas = renderer.getCanvas(); 1466 1467 if (config.autoRotate !== false) { 1468 // When auto-rotating this check needs to happen first (see issue #764) 1469 if (config.yaw > 360) { 1470 config.yaw -= 360; 1471 } else if (config.yaw < -360) { 1472 config.yaw += 360; 1473 } 1474 } 1475 1476 // Keep a tmp value of yaw for autoRotate comparison later 1477 tmpyaw = config.yaw; 1478 1479 // Optionally avoid showing background (empty space) on left or right by adapting min/max yaw 1480 var hoffcut = 0, 1481 voffcut = 0; 1482 if (config.avoidShowingBackground) { 1483 var hfov2 = config.hfov / 2, 1484 vfov2 = Math.atan2(Math.tan(hfov2 / 180 * Math.PI), (canvas.width / canvas.height)) * 180 / Math.PI, 1485 transposed = config.vaov > config.haov; 1486 if (transposed) { 1487 voffcut = vfov2 * (1 - Math.min(Math.cos((config.pitch - hfov2) / 180 * Math.PI), 1488 Math.cos((config.pitch + hfov2) / 180 * Math.PI))); 1489 } else { 1490 hoffcut = hfov2 * (1 - Math.min(Math.cos((config.pitch - vfov2) / 180 * Math.PI), 1491 Math.cos((config.pitch + vfov2) / 180 * Math.PI))); 1492 } 1493 } 1494 1495 // Ensure the yaw is within min and max allowed 1496 var yawRange = config.maxYaw - config.minYaw, 1497 minYaw = -180, 1498 maxYaw = 180; 1499 if (yawRange < 360) { 1500 minYaw = config.minYaw + config.hfov / 2 + hoffcut; 1501 maxYaw = config.maxYaw - config.hfov / 2 - hoffcut; 1502 if (yawRange < config.hfov) { 1503 // Lock yaw to average of min and max yaw when both can be seen at once 1504 minYaw = maxYaw = (minYaw + maxYaw) / 2; 1505 } 1506 config.yaw = Math.max(minYaw, Math.min(maxYaw, config.yaw)); 1507 } 1508 1509 if (!(config.autoRotate !== false)) { 1510 // When not auto-rotating, this check needs to happen after the 1511 // previous check (see issue #698) 1512 if (config.yaw > 360) { 1513 config.yaw -= 360; 1514 } else if (config.yaw < -360) { 1515 config.yaw += 360; 1516 } 1517 } 1518 1519 // Check if we autoRotate in a limited by min and max yaw 1520 // If so reverse direction 1521 if (config.autoRotate !== false && tmpyaw != config.yaw && 1522 prevTime !== undefined) { // this condition prevents changing the direction initially 1523 config.autoRotate *= -1; 1524 } 1525 1526 // Ensure the calculated pitch is within min and max allowed 1527 var vfov = 2 * Math.atan(Math.tan(config.hfov / 180 * Math.PI * 0.5) / 1528 (canvas.width / canvas.height)) / Math.PI * 180; 1529 var minPitch = config.minPitch + vfov / 2, 1530 maxPitch = config.maxPitch - vfov / 2; 1531 var pitchRange = config.maxPitch - config.minPitch; 1532 if (pitchRange < vfov) { 1533 // Lock pitch to average of min and max pitch when both can be seen at once 1534 minPitch = maxPitch = (minPitch + maxPitch) / 2; 1535 } 1536 if (isNaN(minPitch)) 1537 minPitch = -90; 1538 if (isNaN(maxPitch)) 1539 maxPitch = 90; 1540 config.pitch = Math.max(minPitch, Math.min(maxPitch, config.pitch)); 1541 1542 renderer.render(config.pitch * Math.PI / 180, config.yaw * Math.PI / 180, config.hfov * Math.PI / 180, {roll: config.roll * Math.PI / 180}); 1543 1544 renderHotSpots(); 1545 1546 // Update compass 1547 //compass data fired by sakib 1548 // const node = document.getElementsByClassName('add-pulse')[0]; 1549 // if(node) { 1550 // node.style.transform = 'rotate(' + (-config.yaw - config.northOffset) + 'deg)'; 1551 // } 1552 if (config.compass) { 1553 compass.style.transform = 'rotate(' + (-config.yaw - config.northOffset) + 'deg)'; 1554 compass.style.webkitTransform = 'rotate(' + (-config.yaw - config.northOffset) + 'deg)'; 1555 } 1556 } 1557 } 1558 1559 /** 1560 * Creates a new quaternion. 1561 * @private 1562 * @constructor 1563 * @param {Number} w - W value 1564 * @param {Number} x - X value 1565 * @param {Number} y - Y value 1566 * @param {Number} z - Z value 1567 */ 1568 function Quaternion(w, x, y, z) { 1569 this.w = w; 1570 this.x = x; 1571 this.y = y; 1572 this.z = z; 1573 } 1574 1575 /** 1576 * Multiplies quaternions. 1577 * @private 1578 * @param {Quaternion} q - Quaternion to multiply 1579 * @returns {Quaternion} Result of multiplication 1580 */ 1581 Quaternion.prototype.multiply = function(q) { 1582 return new Quaternion(this.w*q.w - this.x*q.x - this.y*q.y - this.z*q.z, 1583 this.x*q.w + this.w*q.x + this.y*q.z - this.z*q.y, 1584 this.y*q.w + this.w*q.y + this.z*q.x - this.x*q.z, 1585 this.z*q.w + this.w*q.z + this.x*q.y - this.y*q.x); 1586 }; 1587 1588 /** 1589 * Converts quaternion to Euler angles. 1590 * @private 1591 * @returns {Number[]} [phi angle, theta angle, psi angle] 1592 */ 1593 Quaternion.prototype.toEulerAngles = function() { 1594 var phi = Math.atan2(2 * (this.w * this.x + this.y * this.z), 1595 1 - 2 * (this.x * this.x + this.y * this.y)), 1596 theta = Math.asin(2 * (this.w * this.y - this.z * this.x)), 1597 psi = Math.atan2(2 * (this.w * this.z + this.x * this.y), 1598 1 - 2 * (this.y * this.y + this.z * this.z)); 1599 return [phi, theta, psi]; 1600 }; 1601 1602 /** 1603 * Converts device orientation API Tait-Bryan angles to a quaternion. 1604 * @private 1605 * @param {Number} alpha - Alpha angle (in degrees) 1606 * @param {Number} beta - Beta angle (in degrees) 1607 * @param {Number} gamma - Gamma angle (in degrees) 1608 * @returns {Quaternion} Orientation quaternion 1609 */ 1610 function taitBryanToQuaternion(alpha, beta, gamma) { 1611 var r = [beta ? beta * Math.PI / 180 / 2 : 0, 1612 gamma ? gamma * Math.PI / 180 / 2 : 0, 1613 alpha ? alpha * Math.PI / 180 / 2 : 0]; 1614 var c = [Math.cos(r[0]), Math.cos(r[1]), Math.cos(r[2])], 1615 s = [Math.sin(r[0]), Math.sin(r[1]), Math.sin(r[2])]; 1616 1617 return new Quaternion(c[0]*c[1]*c[2] - s[0]*s[1]*s[2], 1618 s[0]*c[1]*c[2] - c[0]*s[1]*s[2], 1619 c[0]*s[1]*c[2] + s[0]*c[1]*s[2], 1620 c[0]*c[1]*s[2] + s[0]*s[1]*c[2]); 1621 } 1622 1623 /** 1624 * Computes current device orientation quaternion from device orientation API 1625 * Tait-Bryan angles. 1626 * @private 1627 * @param {Number} alpha - Alpha angle (in degrees) 1628 * @param {Number} beta - Beta angle (in degrees) 1629 * @param {Number} gamma - Gamma angle (in degrees) 1630 * @returns {Quaternion} Orientation quaternion 1631 */ 1632 function computeQuaternion(alpha, beta, gamma) { 1633 // Convert Tait-Bryan angles to quaternion 1634 var quaternion = taitBryanToQuaternion(alpha, beta, gamma); 1635 // Apply world transform 1636 quaternion = quaternion.multiply(new Quaternion(Math.sqrt(0.5), -Math.sqrt(0.5), 0, 0)); 1637 // Apply screen transform 1638 var angle = window.orientation ? -window.orientation * Math.PI / 180 / 2 : 0; 1639 return quaternion.multiply(new Quaternion(Math.cos(angle), 0, -Math.sin(angle), 0)); 1640 } 1641 1642 /** 1643 * Event handler for device orientation API. Controls pointing. 1644 * @private 1645 * @param {DeviceOrientationEvent} event - Device orientation event. 1646 */ 1647 function orientationListener(e) { 1648 var q = computeQuaternion(e.alpha, e.beta, e.gamma).toEulerAngles(); 1649 if (typeof(orientation) == 'number' && orientation < 10) { 1650 // This kludge is necessary because iOS sometimes provides a few stale 1651 // device orientation events when the listener is removed and then 1652 // readded. Thus, we skip the first 10 events to prevent this from 1653 // causing problems. 1654 orientation += 1; 1655 } else if (orientation === 10) { 1656 // Record starting yaw to prevent jumping 1657 orientationYawOffset = q[2] / Math.PI * 180 + config.yaw; 1658 orientation = true; 1659 requestAnimationFrame(animate); 1660 } else { 1661 config.pitch = q[0] / Math.PI * 180; 1662 config.roll = -q[1] / Math.PI * 180; 1663 config.yaw = -q[2] / Math.PI * 180 + orientationYawOffset; 1664 } 1665 } 1666 1667 /** 1668 * Initializes renderer. 1669 * @private 1670 */ 1671 function renderInit() { 1672 try { 1673 var params = {}; 1674 if (config.horizonPitch !== undefined) 1675 params.horizonPitch = config.horizonPitch * Math.PI / 180; 1676 if (config.horizonRoll !== undefined) 1677 params.horizonRoll = config.horizonRoll * Math.PI / 180; 1678 if (config.backgroundColor !== undefined) 1679 params.backgroundColor = config.backgroundColor; 1680 renderer.init(panoImage, config.type, config.dynamic, config.haov * Math.PI / 180, config.vaov * Math.PI / 180, config.vOffset * Math.PI / 180, renderInitCallback, params); 1681 if (config.dynamic !== true) { 1682 // Allow image to be garbage collected 1683 panoImage = undefined; 1684 } 1685 } catch(event) { 1686 // Panorama not loaded 1687 1688 // Display error if there is a bad texture 1689 if (event.type == 'webgl error' || event.type == 'no webgl') { 1690 anError(); 1691 } else if (event.type == 'webgl size error') { 1692 anError(config.strings.textureSizeError.replace('%s', event.width).replace('%s', event.maxWidth)); 1693 } else { 1694 anError(config.strings.unknownError); 1695 throw event; 1696 } 1697 } 1698 } 1699 1700 /** 1701 * Triggered when render initialization finishes. Handles fading between 1702 * scenes as well as showing the compass and hotspots and hiding the loading 1703 * display. 1704 * @private 1705 */ 1706 function renderInitCallback() { 1707 // Fade if specified 1708 if (config.sceneFadeDuration && renderer.fadeImg !== undefined) { 1709 renderer.fadeImg.style.opacity = 0; 1710 // Remove image 1711 var fadeImg = renderer.fadeImg; 1712 delete renderer.fadeImg; 1713 setTimeout(function() { 1714 renderContainer.removeChild(fadeImg); 1715 fireEvent('scenechangefadedone'); 1716 }, config.sceneFadeDuration); 1717 } 1718 1719 // Show compass if applicable 1720 if (config.compass) { 1721 compass.style.display = 'inline'; 1722 } else { 1723 compass.style.display = 'none'; 1724 } 1725 1726 // Show hotspots 1727 createHotSpots(); 1728 1729 // Hide loading display 1730 infoDisplay.load.box.style.display = 'none'; 1731 if (preview !== undefined) { 1732 renderContainer.removeChild(preview); 1733 preview = undefined; 1734 } 1735 loaded = true; 1736 1737 animateInit(); 1738 1739 fireEvent('load'); 1740 } 1741 1742 /** 1743 * Creates hot spot element for the current scene. 1744 * @private 1745 * @param {Object} hs - The configuration for the hotspot 1746 */ 1747 function createHotSpot(hs) { 1748 // Make sure hot spot pitch and yaw are numbers 1749 hs.pitch = Number(hs.pitch) || 0; 1750 hs.yaw = Number(hs.yaw) || 0; 1751 1752 var div = document.createElement('div'); 1753 div.className = 'pnlm-hotspot-base'; 1754 if (hs.cssClass) 1755 div.className += ' ' + hs.cssClass; 1756 else 1757 div.className += ' pnlm-hotspot pnlm-sprite pnlm-' + escapeHTML(hs.type); 1758 1759 //Shahin - customized hotspot dom for Hexagon shape 1760 if(hs.hotspot_shape === 'hexagon'){ 1761 var hotspotShape = document.createElement('div'); 1762 hotspotShape.className = 'hexagon-wrapper'; 1763 const hexagonShapeIcon = '<svg fill="none" width="30" height="25" viewB
1763ox="0 0 40 35" xmlns="http://www.w3.org/2000/svg"><path fill="#00b4ff" d="M0 17.32L10 0h20l10 17.32-10 17.321H10L0 17.321z"/></svg>'; 1764 hotspotShape.innerHTML = hexagonShapeIcon; 1765 div.appendChild(hotspotShape); 1766 } 1767 //Sakib - customized hotspot dom for vr mode 1768 var title = document.createElement('span'); 1769 title.className = 'vr-mode-title'; 1770 if (hs.sceneId) 1771 title.innerHTML = escapeHTML(hs.sceneId); 1772 //Sakib - customized hotspot dom for vr mode end 1773 1774 var span = document.createElement('span'); 1775 if (hs.text) 1776 span.innerHTML = escapeHTML(hs.text); 1777 1778 var a; 1779 if (hs.video) { 1780 var video = document.createElement('video'), 1781 vidp = hs.video; 1782 if (config.basePath && !absoluteURL(vidp)) 1783 vidp = config.basePath + vidp; 1784 video.src = sanitizeURL(vidp); 1785 video.controls = true; 1786 video.style.width = hs.width + 'px'; 1787 renderContainer.appendChild(div); 1788 span.appendChild(video); 1789 } else if (hs.image) { 1790 var imgp = hs.image; 1791 if (config.basePath && !absoluteURL(imgp)) 1792 imgp = config.basePath + imgp; 1793 a = document.createElement('a'); 1794 a.href = sanitizeURL(hs.URL ? hs.URL : imgp, true); 1795 a.target = '_blank'; 1796 span.appendChild(a); 1797 var image = document.createElement('img'); 1798 image.src = sanitizeURL(imgp); 1799 image.style.width = hs.width + 'px'; 1800 image.style.paddingTop = '5px'; 1801 renderContainer.appendChild(div); 1802 a.appendChild(image); 1803 span.style.maxWidth = 'initial'; 1804 } else if (hs.URL) { 1805 a = document.createElement('a'); 1806 a.href = sanitizeURL(hs.URL, true); 1807 if (hs.attributes) { 1808 for (var key in hs.attributes) { 1809 a.setAttribute(key, hs.attributes[key]); 1810 } 1811 } else { 1812 //wpvr edit by sakib for in tab url open// -- handling from here 1813 if (hs.wpvr_url_open == 'on') { 1814 a.target = '_self'; 1815 } 1816 else { 1817 a.target = '_blank'; 1818 } 1819 } 1820 renderContainer.appendChild(a); 1821 div.className += ' pnlm-pointer'; 1822 span.className += ' pnlm-pointer'; 1823 a.appendChild(div); 1824 } else { 1825 if (hs.sceneId) { 1826 div.onclick = div.ontouchend = function() { 1827 if (!div.clicked) { 1828 div.clicked = true; 1829 loadScene(hs.sceneId, hs.targetPitch, hs.targetYaw, hs.targetHfov); 1830 } 1831 return false; 1832 }; 1833 div.className += ' pnlm-pointer'; 1834 span.className += ' pnlm-pointer'; 1835 } 1836 1837 if (hs.sceneId) 1838 div.appendChild(title); 1839 1840 renderContainer.appendChild(div); 1841 } 1842 1843 if (hs.createTooltipFunc) { 1844 hs.createTooltipFunc(div, hs.createTooltipArgs); 1845 } else if (hs.text || hs.video || hs.image) { 1846 div.classList.add('pnlm-tooltip'); 1847 div.appendChild(span); 1848 span.style.width = span.scrollWidth - 20 + 'px'; 1849 span.style.marginLeft = -(span.scrollWidth - div.offsetWidth) / 2 + 'px'; 1850 span.style.marginTop = -span.scrollHeight - 12 + 'px'; 1851 } 1852 if (hs.clickHandlerFunc) { 1853 div.addEventListener('click', function(e) { 1854 hs.clickHandlerFunc(e, hs.clickHandlerArgs); 1855 }, 'false'); 1856 div.className += ' pnlm-pointer'; 1857 span.className += ' pnlm-pointer'; 1858 } 1859 hs.div = div; 1860 } 1861 1862 /** 1863 * Creates hot spot elements for the current scene. 1864 * @private 1865 */ 1866 function createHotSpots() { 1867 if (hotspotsCreated) return; 1868 1869 if (!config.hotSpots) { 1870 config.hotSpots = []; 1871 } else { 1872 // Sort by pitch so tooltip is never obscured by another hot spot 1873 config.hotSpots = config.hotSpots.sort(function(a, b) { 1874 return a.pitch < b.pitch; 1875 });
1876 config.hotSpots.forEach(createHotSpot); 1877 } 1878 hotspotsCreated = true; 1879 renderHotSpots(); 1880 } 1881 1882 /** 1883 * Destroys currently created hot spot elements. 1884 * @private 1885 */ 1886 function destroyHotSpots() { 1887 var hs = config.hotSpots; 1888 hotspotsCreated = false; 1889 delete config.hotSpots; 1890 if (hs) { 1891 for (var i = 0; i < hs.length; i++) { 1892 var current = hs[i].div; 1893 if (current) { 1894 while (current.parentNode && current.parentNode != renderContainer) { 1895 current = current.parentNode; 1896 } 1897 renderContainer.removeChild(current); 1898 } 1899 delete hs[i].div; 1900 } 1901 } 1902 } 1903 1904 /** 1905 * Renders hot spot, updating its position and visibility. 1906 * @private 1907 */ 1908 function renderHotSpot(hs) { 1909 var hsPitchSin = Math.sin(hs.pitch * Math.PI / 180), 1910 hsPitchCos = Math.cos(hs.pitch * Math.PI / 180), 1911 configPitchSin = Math.sin(config.pitch * Math.PI / 180), 1912 configPitchCos = Math.cos(config.pitch * Math.PI / 180), 1913 yawCos = Math.cos((-hs.yaw + config.yaw) * Math.PI / 180); 1914 var z = hsPitchSin * configPitchSin + hsPitchCos * yawCos * configPitchCos; 1915 if ((hs.yaw <= 90 && hs.yaw > -90 && z <= 0) || 1916 ((hs.yaw > 90 || hs.yaw <= -90) && z <= 0)) { 1917 hs.div.style.visibility = 'hidden'; 1918 } else { 1919 var yawSin = Math.sin((-hs.yaw + config.yaw) * Math.PI / 180), 1920 hfovTan = Math.tan(config.hfov * Math.PI / 360); 1921 hs.div.style.visibility = 'visible'; 1922 // Subpixel rendering doesn't work in Firefox 1923 // https://bugzilla.mozilla.org/show_bug.cgi?id=739176 1924 var canvas = renderer.getCanvas(), 1925 canvasWidth = canvas.clientWidth, 1926 canvasHeight = canvas.clientHeight; 1927 var coord = [-canvasWidth / hfovTan * yawSin * hsPitchCos / z / 2, 1928 -canvasWidth / hfovTan * (hsPitchSin * configPitchCos - 1929 hsPitchCos * yawCos * configPitchSin) / z / 2]; 1930 // Apply roll 1931 var rollSin = Math.sin(config.roll * Math.PI / 180), 1932 rollCos = Math.cos(config.roll * Math.PI / 180); 1933 coord = [coord[0] * rollCos - coord[1] * rollSin, 1934 coord[0] * rollSin + coord[1] * rollCos]; 1935 // Apply transform 1936 coord[0] += (canvasWidth - hs.div.offsetWidth) / 2; 1937 coord[1] += (canvasHeight - hs.div.offsetHeight) / 2; 1938 var transform = 'translate(' + coord[0] + 'px, ' + coord[1] + 1939 'px) translateZ(9999px) rotate(' + config.roll + 'deg)'; 1940 if (hs.scale) { 1941 transform += ' scale(' + (origHfov/config.hfov) / z + ')'; 1942 } 1943 hs.div.style.webkitTransform = transform; 1944 hs.div.style.MozTransform = transform; 1945 hs.div.style.transform = transform; 1946 } 1947 } 1948 1949 /** 1950 * Renders hot spots, updating their positions and visibility. 1951 * @private 1952 */ 1953 function renderHotSpots() { 1954 config.hotSpots.forEach(renderHotSpot); 1955 } 1956 1957 /** 1958 * Merges a scene configuration into the current configuration. 1959 * @private 1960 * @param {string} sceneId - Identifier of scene configuration to merge in. 1961 */ 1962 function mergeConfig(sceneId) { 1963 config = {}; 1964 var k, s; 1965 var photoSphereExcludes = ['haov', 'vaov', 'vOffset', 'northOffset', 'horizonPitch', 'horizonRoll']; 1966 specifiedPhotoSphereExcludes = []; 1967 1968 // Merge default config 1969 for (k in defaultConfig) { 1970 if (defaultConfig.hasOwnProperty(k)) { 1971 config[k] = defaultConfig[k]; 1972 } 1973 } 1974 1975 // Merge default scene config 1976 for (k in initialConfig.default) { 1977 if (initialConfig.default.hasOwnProperty(k)) { 1978 if (k == 'strings') { 1979 for (s in initialConfig.default.strings) { 1980 if (initialConfig.default.strings.hasOwnProperty(s)) { 1981 config.strings[s] = escapeHTML(initialConfig.default.strings[s]); 1982 } 1983 } 1984 } else { 1985 config[k] = initialConfig.default[k]; 1986 if (photoSphereExcludes.indexOf(k) >= 0) { 1987 specifiedPhotoSphereExcludes.push(k); 1988 } 1989 } 1990 } 1991 } 1992 1993 // Merge current scene config 1994 if ((sceneId !== null) && (sceneId !== '') && (initialConfig.scenes) && (initialConfig.scenes[sceneId])) { 1995 var scene = initialConfig.scenes[sceneId]; 1996 for (k in scene) { 1997 if (scene.hasOwnProperty(k)) { 1998 if (k == 'strings') { 1999 for (s in scene.strings) { 2000 if (scene.strings.hasOwnProperty(s)) { 2001 config.strings[s] = escapeHTML(scene.strings[s]); 2002 } 2003 } 2004 } else { 2005 config[k] = scene[k]; 2006 if (photoSphereExcludes.indexOf(k) >= 0) { 2007 specifiedPhotoSphereExcludes.push(k); 2008 } 2009 } 2010 } 2011 } 2012 config.scene = sceneId; 2013 } 2014 2015 // Merge initial config 2016 for (k in initialConfig) { 2017 if (initialConfig.hasOwnProperty(k)) { 2018 if (k == 'strings') { 2019 for (s in initialConfig.strings) { 2020 if (initialConfig.strings.hasOwnProperty(s)) { 2021 config.strings[s] = escapeHTML(initialConfig.strings[s]); 2022 } 2023 } 2024 } else { 2025 config[k] = initialConfig[k]; 2026 if (photoSphereExcludes.indexOf(k) >= 0) { 2027 specifiedPhotoSphereExcludes.push(k); 2028 } 2029 } 2030 } 2031 } 2032 } 2033 2034 /** 2035 * Processes configuration options. 2036 * @param {boolean} [isPreview] - Whether or not the preview is being displayed 2037 * @private 2038 */ 2039 function processOptions(isPreview) { 2040 isPreview = isPreview ? isPreview : false;
2041 2042 // Process preview first so it always loads before the browser hits its 2043 // maximum number of connections to a server as can happen with cubic 2044 // panoramas 2045 if (isPreview && 'preview' in config) { 2046 var p = config.preview; 2047 if (config.basePath && !absoluteURL(p)) 2048 p = config.basePath + p; 2049 preview = document.createElement('div'); 2050 preview.className = 'pnlm-preview-img'; 2051 preview.style.backgroundImage = "url('" + sanitizeURLForCss(p) + "')"; 2052 renderContainer.appendChild(preview); 2053 } 2054 2055 // Handle different preview values 2056 var title = config.title, 2057 author = config.author; 2058 if (isPreview) { 2059 if ('previewTitle' in config) 2060 config.title = config.previewTitle; 2061 if ('previewAuthor' in config) 2062 config.author = config.previewAuthor; 2063 } 2064 2065 // Reset title / author display 2066 if (!config.hasOwnProperty('title')) 2067 infoDisplay.title.innerHTML = ''; 2068 if (!config.hasOwnProperty('author')) 2069 infoDisplay.author.innerHTML = ''; 2070 if (!config.hasOwnProperty('title') && !config.hasOwnProperty('author')) 2071 infoDisplay.container.style.display = 'none'; 2072 2073 // Fill in load button label and loading box text 2074 controls.load.innerHTML = '<p>' + config.strings.loadButtonLabel + '</p>'; 2075 infoDisplay.load.boxp.innerHTML = config.strings.loadingLabel; 2076 2077 // Process other options 2078 for (var key in config) { 2079 if (config.hasOwnProperty(key)) { 2080 switch(key) { 2081 case 'title': 2082 infoDisplay.title.innerHTML = escapeHTML(config[key]); 2083 infoDisplay.container.style.display = 'inline'; 2084 break; 2085 2086 case 'author': 2087 var authorText = escapeHTML(config[key]); 2088 if (config.authorURL) { 2089 var authorLink = document.createElement('a'); 2090 authorLink.href = sanitizeURL(config['authorURL'], true); 2091 authorLink.target = '_blank'; 2092 authorLink.innerHTML = escapeHTML(config[key]); 2093 authorText = authorLink.outerHTML; 2094 } 2095 infoDisplay.author.innerHTML = config.strings.bylineLabel.replace('%s', authorText); 2096 infoDisplay.container.style.display = 'inline'; 2097 break; 2098 2099 case 'fallback': 2100 var link = document.createElement('a'); 2101 link.href = sanitizeURL(config[key], true); 2102 link.target = '_blank'; 2103 link.textContent = 'Click here to view this panorama in an alternative viewer.'; 2104 var message = document.createElement('p'); 2105 message.textContent = 'Your browser does not support WebGL.'; 2106 message.appendChild(document.createElement('br')); 2107 message.appendChild(link); 2108 infoDisplay.errorMsg.innerHTML = ''; // Removes all children nodes 2109 infoDisplay.errorMsg.appendChild(message); 2110 break; 2111 2112 case 'hfov': 2113 setHfov(Number(config[key])); 2114 break; 2115 2116 case 'autoLoad': 2117 if (config[key] === true && renderer === undefined) { 2118 // Show loading box 2119 infoDisplay.load.box.style.display = 'inline'; 2120 // Hide load button 2121 controls.load.style.display = 'none'; 2122 // Initialize 2123 init(); 2124 } 2125 break; 2126 2127 case 'showZoomCtrl': 2128 if (config[key] && config.showControls != false) { 2129 // Show zoom controls 2130 controls.zoom.style.display = 'block'; 2131 } else { 2132 // Hide zoom controls 2133 controls.zoom.style.display = 'none'; 2134 } 2135 break; 2136 2137 case 'showFullscreenCtrl': 2138 if (config[key] && config.showControls != false && ('fullscreen' in document || 'mozFullScreen' in document || 2139 'webkitIsFullScreen' in document || 'msFullscreenElement' in document)) { 2140 2141 // Show fullscreen control 2142 controls.fullscreen.style.display = 'block'; 2143 } else { 2144 // Hide fullscreen control 2145 controls.fullscreen.style.display = 'none'; 2146 } 2147 break; 2148 2149 case 'hotSpotDebug': 2150 if (config[key]) 2151 hotSpotDebugIndicator.style.display = 'block'; 2152 else 2153 hotSpotDebugIndicator.style.display = 'none'; 2154 break; 2155 2156 case 'showControls': 2157 if (!config[key]) { 2158 controls.orientation.style.display = 'none'; 2159 controls.zoom.style.display = 'none'; 2160 controls.fullscreen.style.display = 'none'; 2161 } 2162 break; 2163 2164 case 'orientationOnByDefault': 2165 if (config[key]) 2166 startOrientation(); 2167 break; 2168 } 2169 } 2170 } 2171 2172 if (isPreview) { 2173 // Restore original values if changed for preview 2174 if (title) 2175 config.title = title; 2176 else 2177 delete config.title; 2178 if (author) 2179 config.author = author; 2180 else 2181 delete config.author; 2182 } 2183 } 2184 2185 /** 2186 * Toggles fullscreen mode. 2187 * @private 2188 */ 2189 function toggleFullscreen() { 2190 if (loaded && !error) { 2191 if (!fullscreenActive) { 2192 try { 2193 if (container.requestFullscreen) { 2194 container.requestFullscreen(); 2195 } else if (container.mozRequestFullScreen) { 2196 container.mozRequestFullScreen(); 2197 } else if (container.msRequestFullscreen) { 2198 container.msRequestFullscreen(); 2199 } else { 2200 container.webkitRequestFullScreen(); 2201 } 2202 } catch(event) { 2203 // Fullscreen doesn't work 2204 } 2205 } else { 2206 if (document.exitFullscreen) { 2207 document.exitFullscreen(); 2208 } else if (document.mozCancelFullScreen) { 2209 document.mozCancelFullScreen(); 2210 } else if (document.webkitCancelFullScreen) { 2211 document.webkitCancelFullScreen(); 2212 } else if (document.msExitFullscreen) { 2213 document.msExitFullscreen(); 2214 } 2215 } 2216 } 2217 } 2218 2219 /** 2220 * Event handler for fullscreen changes. 2221 * @private 2222 */ 2223 function onFullScreenChange(resize) { 2224 if (document.fullscreenElement || document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement) { 2225 controls.fullscreen.classList.add('pnlm-fullscreen-toggle-button-active'); 2226 fullscreenActive = true; 2227 } else { 2228 controls.fullscreen.classList.remove('pnlm-fullscreen-toggle-button-active'); 2229 fullscreenActive = false;
vendor: 4,274 bytes, lines 2230-2344
2230 } 2231 if (resize !== 'resize') 2232 fireEvent('fullscreenchange', fullscreenActive); 2233 // Resize renderer (deal with browser quirks and fixes #155) 2234 renderer.resize(); 2235 setHfov(config.hfov); 2236 animateInit(); 2237 } 2238 2239 /** 2240 * Increases panorama zoom. For use with zoom button. 2241 * @private 2242 */ 2243 function zoomIn() { 2244 if (loaded) { 2245 setHfov(config.hfov - 5); 2246 animateInit(); 2247 } 2248 } 2249 2250 /** 2251 * Decreases panorama zoom. For use with zoom button. 2252 * @private 2253 */ 2254 function zoomOut() { 2255 if (loaded) { 2256 setHfov(config.hfov + 5); 2257 animateInit(); 2258 } 2259 } 2260 2261 /** 2262 * Clamps horzontal field of view to viewer's limits. 2263 * @private 2264 * @param {number} hfov - Input horizontal field of view (in degrees) 2265 * @return {number} - Clamped horizontal field of view (in degrees) 2266 */ 2267 function constrainHfov(hfov) { 2268 // Keep field of view within bounds 2269 var minHfov = config.minHfov; 2270 if (config.type == 'multires' && renderer && !config.multiResMinHfov) { 2271 minHfov = Math.min(minHfov, renderer.getCanvas().width / (config.multiRes.cubeResolution / 90 * 0.9)); 2272 } 2273 if (minHfov > config.maxHfov) { 2274 // Don't change view if bounds don't make sense 2275 console.log('HFOV bounds do not make sense (minHfov > maxHfov).'); 2276 return config.hfov; 2277 } 2278 var newHfov = config.hfov; 2279 if (hfov < minHfov) { 2280 newHfov = minHfov; 2281 } else if (hfov > config.maxHfov) { 2282 newHfov = config.maxHfov; 2283 } else { 2284 newHfov = hfov; 2285 } 2286 // Optionally avoid showing background (empty space) on top or bottom by adapting newHfov 2287 if (config.avoidShowingBackground && renderer) { 2288 var canvas = renderer.getCanvas(); 2289 newHfov = Math.min(newHfov, 2290 Math.atan(Math.tan((config.maxPitch - config.minPitch) / 360 * Math.PI) / 2291 canvas.height * canvas.width) * 360 / Math.PI); 2292 } 2293 return newHfov; 2294 } 2295 2296 /** 2297 * Sets viewer's horizontal field of view. 2298 * @private 2299 * @param {number} hfov - Desired horizontal field of view in degrees. 2300 */ 2301 function setHfov(hfov) { 2302 config.hfov = constrainHfov(hfov); 2303 fireEvent('zoomchange', config.hfov); 2304 } 2305 2306 /** 2307 * Stops auto rotation and animated moves. 2308 * @private 2309 */ 2310 function stopAnimation() { 2311 animatedMove = {}; 2312 autoRotateSpeed = config.autoRotate ? config.autoRotate : autoRotateSpeed; 2313 config.autoRotate = false; 2314 } 2315 2316 /** 2317 * Loads panorama. 2318 * @private 2319 */ 2320 function load() { 2321 // Since WebGL error handling is very general, first we clear any error box 2322 // since it is a new scene and the error from previous maybe because of lacking 2323 // memory etc and not because of a lack of WebGL support etc 2324 clearError(); 2325 loaded = false; 2326 2327 controls.load.style.display = 'none'; 2328 infoDisplay.load.box.style.display = 'inline'; 2329 init(); 2330 } 2331 2332 /** 2333 * Loads scene. 2334 * @private 2335 * @param {string} sceneId - Identifier of scene configuration to merge in. 2336 * @param {number} targetPitch - Pitch viewer should be centered on once scene loads. 2337 * @param {number} targetYaw - Yaw viewer should be centered on once scene loads. 2338 * @param {number} targetHfov - HFOV viewer should use once scene loads. 2339 * @param {boolean} [fadeDone] - If `true`, fade setup is skipped. 2340 */ 2341 function loadScene(sceneId, targetPitch, targetYaw, targetHfov, fadeDone) { 2342 if (!loaded) 2343 fadeDone = true; // Don't try to fade when there isn't a scene loaded 2344 loaded = false;
2345 animatedMove = {}; 2346 2347 // Set up fade if specified 2348 var fadeImg, workingPitch, workingYaw, workingHfov; 2349 if (config.sceneFadeDuration && !fadeDone) { 2350 var data = renderer.render(config.pitch * Math.PI / 180, config.yaw * Math.PI / 180, config.hfov * Math.PI / 180, {returnImage: true}); 2351 if (data !== undefined) { 2352 fadeImg = new Image(); 2353 fadeImg.className = 'pnlm-fade-img'; 2354 fadeImg.style.transition = 'opacity ' + (config.sceneFadeDuration / 1000) + 's'; 2355 fadeImg.style.width = '100%'; 2356 fadeImg.style.height = '100%'; 2357 fadeImg.onload = function() { 2358 loadScene(sceneId, targetPitch, targetYaw, targetHfov, true); 2359 }; 2360 fadeImg.src = data; 2361 renderContainer.appendChild(fadeImg); 2362 renderer.fadeImg = fadeImg; 2363 return; 2364 } 2365 } 2366 2367 // Set new pointing 2368 if (targetPitch === 'same') { 2369 workingPitch = config.pitch; 2370 } else { 2371 workingPitch = targetPitch; 2372 } 2373 if (targetYaw === 'same') { 2374 workingYaw = config.yaw; 2375 } else if (targetYaw === 'sameAzimuth') { 2376 workingYaw = config.yaw + (config.northOffset || 0) - (initialConfig.scenes[sceneId].northOffset || 0); 2377 } else { 2378 workingYaw = targetYaw; 2379 } 2380 if (targetHfov === 'same') { 2381 workingHfov = config.hfov; 2382 } else { 2383 workingHfov = targetHfov; 2384 } 2385 2386 // Destroy hot spots from previous scene 2387 destroyHotSpots(); 2388 2389 // Create the new config for the scene 2390 mergeConfig(sceneId); 2391 2392 // Stop motion 2393 speed.yaw = speed.pitch = speed.hfov = 0; 2394 2395 // Reload scene 2396 processOptions(); 2397 if (workingPitch !== undefined) { 2398 config.pitch = workingPitch; 2399 } 2400 if (workingYaw !== undefined) { 2401 config.yaw = workingYaw; 2402 } 2403 if (workingHfov !== undefined) { 2404 config.hfov = workingHfov; 2405 } 2406 fireEvent('scenechange', sceneId); 2407 load(); 2408 } 2409 2410 /** 2411 * Stop using device orientation. 2412 * @private 2413 */ 2414 function stopOrientation() { 2415 window.removeEventListener('deviceorientation', orientationListener); 2416 controls.orientation.classList.remove('pnlm-orientation-button-active'); 2417 orientation = false; 2418 } 2419 2420 /** 2421 * Start using device orientation. 2422 * @private 2423 */ 2424 function startOrientation() { 2425 if (!orientationSupport) 2426 return; 2427 if (typeof DeviceMotionEvent !== 'undefined' && 2428 typeof DeviceMotionEvent.requestPermission === 'function') { 2429 DeviceOrientationEvent.requestPermission().then(function(response) { 2430 if (response == 'granted') { 2431 orientation = 1; 2432 window.addEventListener('deviceorientation', orientationListener); 2433 controls.orientation.classList.add('pnlm-orientation-button-active'); 2434 } 2435 }); 2436 } else { 2437 orientation = 1; 2438 window.addEventListener('deviceorientation', orientationListener); 2439 controls.orientation.classList.add('pnlm-orientation-button-active'); 2440 } 2441 } 2442 2443 /** 2444 * Escapes HTML string (to mitigate possible DOM XSS attacks). 2445 * @private 2446 * @param {string} s - String to escape 2447 * @returns {string} Escaped string 2448 */ 2449 function escapeHTML(s) { 2450 if (!initialConfig.escapeHTML) 2451 return String(s).split('\n').join('<br>'); 2452 return String(s).split(/&/g).join('&') 2453 .split('"').join('"') 2454 .split("'").join(''') 2455 .split('<').join('<') 2456 .split('>').join('>') 2457 .split('/').join('/') 2458 .split('\n').join('<br>'); // Allow line breaks 2459 } 2460 2461 /** 2462 * Removes possibility of XSS attacks with URLs.
2463 * The URL cannot be of protocol 'javascript'. 2464 * @private 2465 * @param {string} url - URL to sanitize 2466 * @param {boolean} href - True if URL is for link (blocks data URIs) 2467 * @returns {string} Sanitized URL 2468 */ 2469 function sanitizeURL(url, href) { 2470 try { 2471 var decoded_url = decodeURIComponent(unescape(url)).replace(/[^\w:]/g, '').toLowerCase(); 2472 } catch (e) { 2473 return 'about:blank'; 2474 } 2475 if (decoded_url.indexOf('javascript:') === 0 || 2476 decoded_url.indexOf('vbscript:') === 0) { 2477 console.log('Script URL removed.'); 2478 return 'about:blank'; 2479 } 2480 if (href && decoded_url.indexOf('data:') === 0) { 2481 console.log('Data URI removed from link.'); 2482 return 'about:blank'; 2483 } 2484 return url; 2485 } 2486 2487 /** 2488 * Unescapes HTML entities. 2489 * Copied from Marked.js 0.7.0. 2490 * @private 2491 * @param {string} url - URL to sanitize 2492 * @param {boolean} href - True if URL is for link (blocks data URIs) 2493 * @returns {string} Sanitized URL 2494 */ 2495 function unescape(html) { 2496 // Explicitly match decimal, hex, and named HTML entities 2497 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) { 2498 n = n.toLowerCase(); 2499 if (n === 'colon') return ':'; 2500 if (n.charAt(0) === '#') { 2501 return n.charAt(1) === 'x' 2502 ? String.fromCharCode(parseInt(n.substring(2), 16)) 2503 : String.fromCharCode(+n.substring(1)); 2504 } 2505 return ''; 2506 }); 2507 } 2508 2509 /** 2510 * Removes possibility of XSS atacks with URLs for CSS. 2511 * The URL will be sanitized with `sanitizeURL()` and single quotes 2512 * and double quotes escaped. 2513 * @private 2514 * @param {string} url - URL to sanitize 2515 * @returns {string} Sanitized URL 2516 */ 2517 function sanitizeURLForCss(url) { 2518 return sanitizeURL(url) 2519 .replace(/"/g, '%22') 2520 .replace(/'/g, '%27'); 2521 } 2522 2523 /** 2524 * Checks whether or not a panorama is loaded. 2525 * @memberof Viewer 2526 * @instance 2527 * @returns {boolean} `true` if a panorama is loaded, else `false` 2528 */ 2529 this.isLoaded = function() { 2530 return Boolean(loaded); 2531 }; 2532 2533 /** 2534 * Returns the pitch of the center of the view. 2535 * @memberof Viewer 2536 * @instance 2537 * @returns {number} Pitch in degrees 2538 */ 2539 this.getPitch = function() { 2540 return config.pitch; 2541 }; 2542 2543 /** 2544 * Sets the pitch of the center of the view. 2545 * @memberof Viewer 2546 * @instance 2547 * @param {number} pitch - Pitch in degrees 2548 * @param {boolean|number} [animated=1000] - Animation duration in milliseconds or false for no animation 2549 * @param {function} [callback] - Function to call when animation finishes 2550 * @param {object} [callbackArgs] - Arguments to pass to callback function 2551 * @returns {Viewer} `this` 2552 */ 2553 this.setPitch = function(pitch, animated, callback, callbackArgs) { 2554 latestInteraction = Date.now(); 2555 if (Math.abs(pitch - config.pitch) <= eps) { 2556 if (typeof callback == 'function') 2557 callback(callbackArgs); 2558 return this; 2559 } 2560 animated = animated == undefined ? 1000: Number(animated); 2561 if (animated) { 2562 animatedMove.pitch = { 2563 'startTime': Date.now(), 2564 'startPosition': config.pitch, 2565 'endPosition': pitch, 2566 'duration': animated 2567 }; 2568 if (typeof callback == 'function') 2569 setTimeout(function(){callback(callbackArgs);}, animated); 2570 } else { 2571 config.pitch = pitch; 2572 } 2573 animateInit(); 2574 return this; 2575 }; 2576 2577 /** 2578 * Returns the minimum and maximum allowed pitches (in degrees). 2579 * @memberof Viewer 2580 * @instance 2581 * @returns {number[]} [minimum pitch, maximum pitch] 2582 */ 2583 this.getPitchBounds = function() { 2584 return [config.minPitch, config.maxPitch]; 2585 }; 2586 2587 /** 2588 * Set the minimum and maximum allowed pitches (in degrees). 2589 * @memberof Viewer 2590 * @instance 2591 * @param {number[]} bounds - [minimum pitch, maximum pitch] 2592 * @returns {Viewer} `this` 2593 */
2594 this.setPitchBounds = function(bounds) { 2595 config.minPitch = Math.max(-90, Math.min(bounds[0], 90)); 2596 config.maxPitch = Math.max(-90, Math.min(bounds[1], 90)); 2597 return this; 2598 }; 2599 2600 /** 2601 * Returns the yaw of the center of the view. 2602 * @memberof Viewer 2603 * @instance 2604 * @returns {number} Yaw in degrees 2605 */ 2606 this.getYaw = function() { 2607 return (config.yaw + 540) % 360 - 180; 2608 }; 2609 2610 /** 2611 * Sets the yaw of the center of the view. 2612 * @memberof Viewer 2613 * @instance 2614 * @param {number} yaw - Yaw in degrees [-180, 180] 2615 * @param {boolean|number} [animated=1000] - Animation duration in milliseconds or false for no animation 2616 * @param {function} [callback] - Function to call when animation finishes 2617 * @param {object} [callbackArgs] - Arguments to pass to callback function 2618 * @returns {Viewer} `this` 2619 */ 2620 this.setYaw = function(yaw, animated, callback, callbackArgs) { 2621 latestInteraction = Date.now(); 2622 if (Math.abs(yaw - config.yaw) <= eps) { 2623 if (typeof callback == 'function') 2624 callback(callbackArgs); 2625 return this; 2626 } 2627 animated = animated == undefined ? 1000: Number(animated); 2628 yaw = ((yaw + 180) % 360) - 180; // Keep in bounds 2629 if (animated) { 2630 // Animate in shortest direction 2631 if (config.yaw - yaw > 180) 2632 yaw += 360; 2633 else if (yaw - config.yaw > 180) 2634 yaw -= 360; 2635 2636 animatedMove.yaw = { 2637 'startTime': Date.now(), 2638 'startPosition': config.yaw, 2639 'endPosition': yaw, 2640 'duration': animated 2641 }; 2642 if (typeof callback == 'function') 2643 setTimeout(function(){callback(callbackArgs);}, animated); 2644 } else { 2645 config.yaw = yaw; 2646 } 2647 animateInit(); 2648 return this; 2649 }; 2650 2651 /** 2652 * Returns the minimum and maximum allowed pitches (in degrees). 2653 * @memberof Viewer 2654 * @instance 2655 * @returns {number[]} [yaw pitch, maximum yaw] 2656 */ 2657 this.getYawBounds = function() { 2658 return [config.minYaw, config.maxYaw]; 2659 }; 2660 2661 /** 2662 * Set the minimum and maximum allowed yaws (in degrees [-360, 360]). 2663 * @memberof Viewer 2664 * @instance 2665 * @param {number[]} bounds - [minimum yaw, maximum yaw] 2666 * @returns {Viewer} `this` 2667 */ 2668 this.setYawBounds = function(bounds) { 2669 config.minYaw = Math.max(-360, Math.min(bounds[0], 360)); 2670 config.maxYaw = Math.max(-360, Math.min(bounds[1], 360)); 2671 return this; 2672 }; 2673 2674 /** 2675 * Returns the horizontal field of view. 2676 * @memberof Viewer 2677 * @instance 2678 * @returns {number} Horizontal field of view in degrees 2679 */ 2680 this.getHfov = function() { 2681 return config.hfov; 2682 }; 2683 2684 /** 2685 * Sets the horizontal field of view. 2686 * @memberof Viewer 2687 * @instance 2688 * @param {number} hfov - Horizontal field of view in degrees 2689 * @param {boolean|number} [animated=1000] - Animation duration in milliseconds or false for no animation 2690 * @param {function} [callback] - Function to call when animation finishes 2691 * @param {object} [callbackArgs] - Arguments to pass to callback function 2692 * @returns {Viewer} `this` 2693 */ 2694 this.setHfov = function(hfov, animated, callback, callbackArgs) { 2695 latestInteraction = Date.now(); 2696 if (Math.abs(hfov - config.hfov) <= eps) { 2697 if (typeof callback == 'function') 2698 callback(callbackArgs); 2699 return this; 2700 } 2701 animated = animated == undefined ? 1000: Number(animated); 2702 if (animated) { 2703 animatedMove.hfov = { 2704 'startTime': Date.now(), 2705 'startPosition': config.hfov, 2706 'endPosition': constrainHfov(hfov), 2707 'duration': animated 2708 }; 2709 if (typeof callback == 'function') 2710 setTimeout(function(){callback(callbackArgs);}, animated); 2711 } else { 2712 setHfov(hfov); 2713 } 2714 animateInit(); 2715 return this; 2716 }; 2717 2718 /** 2719 * Returns the minimum and maximum allowed horizontal fields of view 2720 * (in degrees). 2721 * @memberof Viewer 2722 * @instance 2723 * @returns {number[]} [minimum hfov, maximum hfov] 2724 */ 2725 this.getHfovBounds = function() { 2726 return [config.minHfov, config.maxHfov]; 2727 }; 2728 2729 /** 2730 * Set the minimum and maximum allowed horizontal fields of view (in degrees). 2731 * @memberof Viewer 2732 * @instance 2733 * @param {number[]} bounds - [minimum hfov, maximum hfov] 2734 * @returns {Viewer} `this` 2735 */
2736 this.setHfovBounds = function(bounds) { 2737 config.minHfov = Math.max(0, bounds[0]); 2738 config.maxHfov = Math.max(0, bounds[1]); 2739 return this; 2740 }; 2741 2742 /** 2743 * Set a new view. Any parameters not specified remain the same. 2744 * @memberof Viewer 2745 * @instance 2746 * @param {number} [pitch] - Target pitch 2747 * @param {number} [yaw] - Target yaw 2748 * @param {number} [hfov] - Target hfov 2749 * @param {boolean|number} [animated=1000] - Animation duration in milliseconds or false for no animation 2750 * @param {function} [callback] - Function to call when animation finishes 2751 * @param {object} [callbackArgs] - Arguments to pass to callback function 2752 * @returns {Viewer} `this` 2753 */ 2754 this.lookAt = function(pitch, yaw, hfov, animated, callback, callbackArgs) { 2755 animated = animated == undefined ? 1000: Number(animated); 2756 if (pitch !== undefined && Math.abs(pitch - config.pitch) > eps) { 2757 this.setPitch(pitch, animated, callback, callbackArgs); 2758 callback = undefined; 2759 } 2760 if (yaw !== undefined && Math.abs(yaw - config.yaw) > eps) { 2761 this.setYaw(yaw, animated, callback, callbackArgs); 2762 callback = undefined; 2763 } 2764 if (hfov !== undefined && Math.abs(hfov - config.hfov) > eps) { 2765 this.setHfov(hfov, animated, callback, callbackArgs); 2766 callback = undefined; 2767 } 2768 if (typeof callback == 'function') 2769 callback(callbackArgs); 2770 return this; 2771 }; 2772 2773 /** 2774 * Returns the panorama's north offset. 2775 * @memberof Viewer 2776 * @instance 2777 * @returns {number} North offset in degrees 2778 */ 2779 this.getNorthOffset = function() { 2780 return config.northOffset; 2781 }; 2782 2783 /** 2784 * Sets the panorama's north offset. 2785 * @memberof Viewer 2786 * @instance 2787 * @param {number} heading - North offset in degrees 2788 * @returns {Viewer} `this` 2789 */ 2790 this.setNorthOffset = function(heading) { 2791 config.northOffset = Math.min(360, Math.max(0, heading)); 2792 animateInit(); 2793 return this; 2794 }; 2795 2796 /** 2797 * Returns the panorama's horizon roll. 2798 * @memberof Viewer 2799 * @instance 2800 * @returns {number} Horizon roll in degrees 2801 */ 2802 this.getHorizonRoll = function() { 2803 return config.horizonRoll; 2804 }; 2805 2806 /** 2807 * Sets the panorama's horizon roll. 2808 * @memberof Viewer 2809 * @instance 2810 * @param {number} roll - Horizon roll in degrees [-90, 90] 2811 * @returns {Viewer} `this` 2812 */ 2813 this.setHorizonRoll = function(roll) { 2814 config.horizonRoll = Math.min(90, Math.max(-90, roll)); 2815 renderer.setPose(config.horizonPitch * Math.PI / 180, config.horizonRoll * Math.PI / 180); 2816 animateInit(); 2817 return this; 2818 }; 2819 2820 /** 2821 * Returns the panorama's horizon pitch. 2822 * @memberof Viewer 2823 * @instance 2824 * @returns {number} Horizon pitch in degrees 2825 */ 2826 this.getHorizonPitch = function() { 2827 return config.horizonPitch; 2828 }; 2829 2830 /** 2831 * Sets the panorama's horizon pitch. 2832 * @memberof Viewer 2833 * @instance 2834 * @param {number} pitch - Horizon pitch in degrees [-90, 90] 2835 * @returns {Viewer} `this` 2836 */ 2837 this.setHorizonPitch = function(pitch) { 2838 config.horizonPitch = Math.min(90, Math.max(-90, pitch)); 2839 renderer.setPose(config.horizonPitch * Math.PI / 180, config.horizonRoll * Math.PI / 180); 2840 animateInit(); 2841 return this; 2842 }; 2843 2844 /** 2845 * Start auto rotation. 2846 * 2847 * Before starting rotation, the viewer is panned to `pitch`. 2848 * @memberof Viewer 2849 * @instance 2850 * @param {number}
2850 [speed] - Auto rotation speed / direction. If not specified, previous value is used. 2851 * @param {number} [pitch] - The pitch to rotate at. If not specified, inital pitch is used. 2852 * @returns {Viewer} `this` 2853 */ 2854 this.startAutoRotate = function(speed, pitch) { 2855 speed = speed || autoRotateSpeed || 1; 2856 pitch = pitch === undefined ? origPitch : pitch; 2857 config.autoRotate = speed; 2858 _this.lookAt(pitch, undefined, origHfov, 3000); 2859 animateInit(); 2860 return this; 2861 }; 2862 2863 /** 2864 * Stop auto rotation. 2865 * @memberof Viewer 2866 * @instance 2867 * @returns {Viewer} `this` 2868 */ 2869 this.stopAutoRotate = function() { 2870 autoRotateSpeed = config.autoRotate ? config.autoRotate : autoRotateSpeed; 2871 config.autoRotate = false; 2872 config.autoRotateInactivityDelay = -1; 2873 return this; 2874 }; 2875 2876 /** 2877 * Stops all movement. 2878 * @memberof Viewer 2879 * @instance 2880 */ 2881 this.stopMovement = function() { 2882 stopAnimation(); 2883 speed = {'yaw': 0, 'pitch': 0, 'hfov': 0}; 2884 }; 2885 2886 /** 2887 * Returns the panorama renderer. 2888 * @memberof Viewer 2889 * @instance 2890 * @returns {Renderer} 2891 */ 2892 this.getRenderer = function() { 2893 return renderer; 2894 }; 2895 2896 /** 2897 * Sets update flag for dynamic content. 2898 * @memberof Viewer 2899 * @instance 2900 * @param {boolean} bool - Whether or not viewer should update even when still 2901 * @returns {Viewer} `this` 2902 */ 2903 this.setUpdate = function(bool) { 2904 update = bool === true; 2905 if (renderer === undefined) 2906 onImageLoad(); 2907 else 2908 animateInit(); 2909 return this; 2910 }; 2911 2912 /** 2913 * Calculate panorama pitch and yaw from location of mouse event. 2914 * @memberof Viewer 2915 * @instance 2916 * @param {MouseEvent} event - Document mouse down event. 2917 * @returns {number[]} [pitch, yaw] 2918 */ 2919 this.mouseEventToCoords = function(event) { 2920 return mouseEventToCoords(event); 2921 }; 2922 2923 /** 2924 * Change scene being viewed. 2925 * @memberof Viewer 2926 * @instance 2927 * @param {string} sceneId - Identifier of scene to switch to. 2928 * @param {number} [pitch] - Pitch to use with new scene 2929 * @param {number} [yaw] - Yaw to use with new scene 2930 * @param {number} [hfov] - HFOV to use with new scene 2931 * @returns {Viewer} `this` 2932 */ 2933 this.loadScene = function(sceneId, pitch, yaw, hfov) { 2934 if (loaded !== false) 2935 loadScene(sceneId, pitch, yaw, hfov); 2936 return this; 2937 }; 2938 2939 /** 2940 * Get ID of current scene. 2941 * @memberof Viewer 2942 * @instance 2943 * @returns {string} ID of current scene 2944 */
2945 this.getScene = function() { 2946 return config.scene; 2947 }; 2948 2949 /** 2950 * Add a new scene. 2951 * @memberof Viewer 2952 * @instance 2953 * @param {string} sceneId - The ID of the new scene 2954 * @param {string} config - The configuration of the new scene 2955 * @returns {Viewer} `this` 2956 */ 2957 this.addScene = function(sceneId, config) { 2958 initialConfig.scenes[sceneId] = config; 2959 return this; 2960 }; 2961 2962 /** 2963 * Remove a scene. 2964 * @memberof Viewer 2965 * @instance 2966 * @param {string} sceneId - The ID of the scene 2967 * @returns {boolean} False if the scene is the current scene or if the scene doesn't exists, else true 2968 */ 2969 this.removeScene = function(sceneId) { 2970 if (config.scene === sceneId || !initialConfig.scenes.hasOwnProperty(sceneId)) 2971 return false; 2972 delete initialConfig.scenes[sceneId]; 2973 return true; 2974 }; 2975 2976 /** 2977 * Toggle fullscreen. 2978 * @memberof Viewer 2979 * @instance 2980 * @returns {Viewer} `this` 2981 */ 2982 this.toggleFullscreen = function() { 2983 toggleFullscreen(); 2984 return this; 2985 }; 2986 2987 /** 2988 * Get configuration of current scene. 2989 * @memberof Viewer 2990 * @instance 2991 * @returns {Object} Configuration of current scene 2992 */ 2993 this.getConfig = function() { 2994 return config; 2995 }; 2996 2997 /** 2998 * Get viewer's container element. 2999 * @memberof Viewer 3000 * @instance 3001 * @returns {HTMLElement} Container `div` element 3002 */ 3003 this.getContainer = function() { 3004 return container; 3005 }; 3006 3007 /** 3008 * Add a new hot spot. 3009 * @memberof Viewer 3010 * @instance 3011 * @param {Object} hs - The configuration for the hot spot 3012 * @param {string} [sceneId] - Adds hot spot to specified scene if provided, else to current scene 3013 * @returns {Viewer} `this` 3014 * @throws Throws an error if the scene ID is provided but invalid 3015 */ 3016 this.addHotSpot = function(hs, sceneId) { 3017 if (sceneId === undefined && config.scene === undefined) { 3018 // Not a tour 3019 config.hotSpots.push(hs); 3020 } else { 3021 // Tour 3022 var id = sceneId !== undefined ? sceneId : config.scene; 3023 if (initialConfig.scenes.hasOwnProperty(id)) { 3024 if (!initialConfig.scenes[id].hasOwnProperty('hotSpots')) { 3025 initialConfig.scenes[id].hotSpots = []; // Create hot spots array if needed 3026 if (id == config.scene) 3027 config.hotSpots = initialConfig.scenes[id].hotSpots; // Link to current config 3028 } 3029 initialConfig.scenes[id].hotSpots.push(hs); // Add hot spot to config 3030 } else { 3031 throw 'Invalid scene ID!'; 3032 } 3033 } 3034 if (sceneId === undefined || config.scene == sceneId) { 3035 // Add to current scene 3036 createHotSpot(hs); 3037 if (loaded) 3038 renderHotSpot(hs); 3039 } 3040 return this; 3041 }; 3042 3043 /** 3044 * Remove a hot spot. 3045 * @memberof Viewer 3046 * @instance 3047 * @param {string} hotSpotId - The ID of the hot spot 3048 * @param {string} [sceneId] - Removes hot spot from specified scene if provided, else from current scene 3049 * @returns {boolean} True if deletion is successful, else false 3050 */ 3051 this.removeHotSpot = function(hotSpotId, sceneId) { 3052 if (sceneId === undefined || config.scene == sceneId) { 3053 if (!config.hotSpots) 3054 return false; 3055 for (var i = 0; i < config.hotSpots.length; i++) { 3056 if (config.hotSpots[i].hasOwnProperty('id') && 3057 config.hotSpots[i].id === hotSpotId) { 3058 // Delete hot spot DOM elements 3059 var current = config.hotSpots[i].div; 3060 while (current.parentNode != renderContainer) 3061 current = current.parentNode; 3062 renderContainer.removeChild(current); 3063 delete config.hotSpots[i].div; 3064 // Remove hot spot from configuration 3065 config.hotSpots.splice(i, 1); 3066 return true; 3067 } 3068 } 3069 } else { 3070 if (initialConfig.scenes.hasOwnProperty(sceneId)) { 3071 if (!initialConfig.scenes[sceneId].hasOwnProperty('hotSpots')) 3072 return false;
vendor: 7,882 bytes, lines 3073-3275
3073 for (var j = 0; j < initialConfig.scenes[sceneId].hotSpots.length; j++) { 3074 if (initialConfig.scenes[sceneId].hotSpots[j].hasOwnProperty('id') && 3075 initialConfig.scenes[sceneId].hotSpots[j].id === hotSpotId) { 3076 // Remove hot spot from configuration 3077 initialConfig.scenes[sceneId].hotSpots.splice(j, 1); 3078 return true; 3079 } 3080 } 3081 } else { 3082 return false; 3083 } 3084 } 3085 }; 3086 3087 /** 3088 * This method should be called if the viewer's container is resized. 3089 * @memberof Viewer 3090 * @instance 3091 */ 3092 this.resize = function() { 3093 if (renderer) 3094 onDocumentResize(); 3095 }; 3096 3097 /** 3098 * Check if a panorama is loaded. 3099 * @memberof Viewer 3100 * @instance 3101 * @returns {boolean} True if a panorama is loaded, else false 3102 */ 3103 this.isLoaded = function() { 3104 return loaded; 3105 }; 3106 3107 /** 3108 * Check if device orientation control is supported. 3109 * @memberof Viewer 3110 * @instance 3111 * @returns {boolean} True if supported, else false 3112 */ 3113 this.isOrientationSupported = function() { 3114 return orientationSupport || false; 3115 }; 3116 3117 /** 3118 * Stop using device orientation. 3119 * @memberof Viewer 3120 * @instance 3121 */ 3122 this.stopOrientation = function() { 3123 stopOrientation(); 3124 }; 3125 3126 /** 3127 * Start using device orientation (does nothing if not supported). 3128 * @memberof Viewer 3129 * @instance 3130 */ 3131 this.startOrientation = function() { 3132 if (orientationSupport) 3133 startOrientation(); 3134 }; 3135 3136 /** 3137 * Check if device orientation control is currently activated. 3138 * @memberof Viewer 3139 * @instance 3140 * @returns {boolean} True if active, else false 3141 */ 3142 this.isOrientationActive = function() { 3143 return Boolean(orientation); 3144 }; 3145 3146 /** 3147 * Subscribe listener to specified event. 3148 * @memberof Viewer 3149 * @instance 3150 * @param {string} type - Type of event to subscribe to. 3151 * @param {Function} listener - Listener function to subscribe to event. 3152 * @returns {Viewer} `this` 3153 */ 3154 this.on = function(type, listener) { 3155 externalEventListeners[type] = externalEventListeners[type] || []; 3156 externalEventListeners[type].push(listener); 3157 return this; 3158 }; 3159 3160 /** 3161 * Remove an event listener (or listeners). 3162 * @memberof Viewer 3163 * @param {string} [type] - Type of event to remove listeners from. If not specified, all listeners are removed. 3164 * @param {Function} [listener] - Listener function to remove. If not specified, all listeners of specified type are removed. 3165 * @returns {Viewer} `this` 3166 */ 3167 this.off = function(type, listener) { 3168 if (!type) { 3169 // Remove all listeners if type isn't specified 3170 externalEventListeners = {}; 3171 return this; 3172 } 3173 if (listener) { 3174 var i = externalEventListeners[type].indexOf(listener); 3175 if (i >= 0) { 3176 // Remove listener if found 3177 externalEventListeners[type].splice(i, 1); 3178 } 3179 if (externalEventListeners[type].length == 0) { 3180 // Remove category if empty 3181 delete externalEventListeners[type]; 3182 } 3183 } else { 3184 // Remove category of listeners if listener isn't specified 3185 delete externalEventListeners[type]; 3186 } 3187 return this; 3188 }; 3189 3190 /** 3191 * Fire listeners attached to specified event. 3192 * @private 3193 * @param {string} [type] - Type of event to fire listeners for. 3194 */ 3195 function fireEvent(type) { 3196 if (type in externalEventListeners) { 3197 // Reverse iteration is useful, if event listener is removed inside its definition 3198 for (var i = externalEventListeners[type].length; i > 0; i--) { 3199 externalEventListeners[type][externalEventListeners[type].length - i].apply(null, [].slice.call(arguments, 1)); 3200 } 3201 } 3202 } 3203 3204 /** 3205 * Destructor. 3206 * @instance 3207 * @memberof Viewer 3208 */ 3209 this.destroy = function() { 3210 destroyed = true; 3211 clearTimeout(autoRotateStart); 3212 3213 if (renderer) 3214 renderer.destroy(); 3215 if (listenersAdded) { 3216 document.removeEventListener('mousemove', onDocumentMouseMove, false); 3217 document.removeEventListener('compasschange', onDocumentCompassChange, false); 3218 document.removeEventListener('mouseup', onDocumentMouseUp, false); 3219 container.removeEventListener('mozfullscreenchange', onFullScreenChange, false); 3220 container.removeEventListener('webkitfullscreenchange', onFullScreenChange, false); 3221 container.removeEventListener('msfullscreenchange', onFullScreenChange, false); 3222 container.removeEventListener('fullscreenchange', onFullScreenChange, false); 3223 window.removeEventListener('resize', onDocumentResize, false); 3224 window.removeEventListener('orientationchange', onDocumentResize, false); 3225 container.removeEventListener('keydown', onDocumentKeyPress, false); 3226 container.removeEventListener('keyup', onDocumentKeyUp, false); 3227 container.removeEventListener('blur', clearKeys, false); 3228 document.removeEventListener('mouseleave', onDocumentMouseUp, false); 3229 } 3230 container.innerHTML = ''; 3231 container.classList.remove('pnlm-container'); 3232 }; 3233 3234 } 3235 3236 return { 3237 viewer: function(container, config) { 3238 return new Viewer(container, config); 3239 } 3240 }; 3241 3242})(window, document); 3243// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/public/lib/pannellum/src/js/libpannellum.js?ver=1 3244/* 3245 * libpannellum - A WebGL and CSS 3D transform based Panorama Renderer 3246 * Copyright (c) 2012-2019 Matthew Petroff 3247 * 3248 * Permission is hereby granted, free of charge, to any person obtaining a copy 3249 * of this software and associated documentation files (the "Software"), to deal 3250 * in the Software without restriction, including without limitation the rights 3251 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 3252 * copies of the Software, and to permit persons to whom the Software is 3253 * furnished to do so, subject to the following conditions: 3254 * 3255 * The above copyright notice and this permission notice shall be included in 3256 * all copies or substantial portions of the Software. 3257 * 3258 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 3259 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 3260 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 3261 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 3262 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 3263 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 3264 * THE SOFTWARE. 3265 */ 3266 3267window.libpannellum = (function(window, document, undefined) { 3268 3269'use strict'; 3270 3271/** 3272 * Creates a new panorama renderer. 3273 * @constructor 3274 * @param {HTMLElement} container - The container element for the renderer. 3275 */
3276function Renderer(container) { 3277 var canvas = document.createElement('canvas'); 3278 canvas.style.width = canvas.style.height = '100%'; 3279 container.appendChild(canvas); 3280 3281 var program, gl, vs, fs; 3282 var fallbackImgSize; 3283 var world; 3284 var vtmps; 3285 var pose; 3286 var image, imageType, dynamic; 3287 var texCoordBuffer, cubeVertBuf, cubeVertTexCoordBuf, cubeVertIndBuf; 3288 var globalParams; 3289 3290 /** 3291 * Initialize renderer. 3292 * @memberof Renderer 3293 * @instance 3294 * @param {Image|Array|Object} image - Input image; format varies based on 3295 * `imageType`. For `equirectangular`, this is an image; for 3296 * `cubemap`, this is an array of images for the cube faces in the 3297 * order [+z, +x, -z, -x, +y, -y]; for `multires`, this is a 3298 * configuration object. 3299 * @param {string} imageType - The type of the image: `equirectangular`, 3300 * `cubemap`, or `multires`. 3301 * @param {boolean} dynamic - Whether or not the image is dynamic (e.g. video). 3302 * @param {number} haov - Initial horizontal angle of view. 3303 * @param {number} vaov - Initial vertical angle of view. 3304 * @param {number} voffset - Initial vertical offset angle. 3305 * @param {function} callback - Load callback function. 3306 * @param {Object} [params] - Other configuration parameters (`horizonPitch`, `horizonRoll`, `backgroundColor`). 3307 */ 3308 this.init = function(_image, _imageType, _dynamic, haov, vaov, voffset, callback, params) { 3309 // Default argument for image type 3310 if (_imageType === undefined) 3311 _imageType = 'equirectangular'; 3312 3313 if (_imageType != 'equirectangular' && _imageType != 'cubemap' && 3314 _imageType != 'multires') { 3315 console.log('Error: invalid image type specified!'); 3316 throw {type: 'config error'}; 3317 } 3318 3319 imageType = _imageType; 3320 image = _image; 3321 dynamic = _dynamic; 3322 globalParams = params || {}; 3323 3324 // Clear old data 3325 if (program) { 3326 if (vs) { 3327 gl.detachShader(program, vs); 3328 gl.deleteShader(vs); 3329 } 3330 if (fs) { 3331 gl.detachShader(program, fs); 3332 gl.deleteShader(fs); 3333 } 3334 gl.bindBuffer(gl.ARRAY_BUFFER, null); 3335 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 3336 if (program.texture) 3337 gl.deleteTexture(program.texture); 3338 if (program.nodeCache) 3339 for (var i = 0; i < program.nodeCache.length; i++) 3340 gl.deleteTexture(program.nodeCache[i].texture); 3341 gl.deleteProgram(program); 3342 program = undefined; 3343 } 3344 pose = undefined; 3345 3346 var s; 3347 var faceMissing = false; 3348 var cubeImgWidth; 3349 if (imageType == 'cubemap') { 3350 for (s = 0; s < 6; s++) { 3351 if (image[s].width > 0) { 3352 if (cubeImgWidth === undefined) 3353 cubeImgWidth = image[s].width; 3354 if (cubeImgWidth != image[s].width) 3355 console.log('Cube faces have inconsistent widths: ' + cubeImgWidth + ' vs. ' + image[s].width); 3356 } else 3357 faceMissing = true; 3358 } 3359 } 3360 function fillMissingFaces(imgSize) { 3361 if (faceMissing) { // Fill any missing fallback/cubemap faces with background 3362 var nbytes = imgSize * imgSize * 4; // RGB, plus non-functional alpha 3363 var imageArray = new Uint8ClampedArray(nbytes); 3364 var rgb = params.backgroundColor ? params.backgroundColor : [0, 0, 0]; 3365 rgb[0] *= 255; 3366 rgb[1] *= 255; 3367 rgb[2] *= 255; 3368 // Maybe filling could be done faster, see e.g. https://stackoverflow.com/questions/1295584/most-efficient-way-to-create-a-zero-filled-javascript-array 3369 for (var i = 0; i < nbytes; i++) { 3370 imageArray[i++] = rgb[0]; 3371 imageArray[i++] = rgb[1]; 3372 imageArray[i++] = rgb[2]; 3373 } 3374 var backgroundSquare = new ImageData(imageArray, imgSize, imgSize); 3375 for (s = 0; s < 6; s++) { 3376 if (image[s].width == 0) 3377 image[s] = backgroundSquare; 3378 } 3379 } 3380 } 3381 3382 // This awful browser specific test exists because iOS 8/9 and IE 11 3383 // don't display non-power-of-two cubemap textures but also don't 3384 // throw an error (tested on an iPhone 5c / iOS 8.1.3 / iOS 9.2 / 3385 // iOS 10.3.1). 3386 // Therefore, the WebGL context is never created for these browsers for 3387 // NPOT cubemaps, and the CSS 3D transform fallback renderer is used 3388 // instead. 3389 if (!(imageType == 'cubemap' && 3390 (cubeImgWidth & (cubeImgWidth - 1)) !== 0 &&
3391 (navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad).* os 8_/) || 3392 navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad).* os 9_/) || 3393 navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad).* os 10_/) || 3394 navigator.userAgent.match(/Trident.*rv[ :]*11\./)))) { 3395 // Enable WebGL on canvas 3396 if (!gl) 3397 gl = canvas.getContext('experimental-webgl', {alpha: false, depth: false}); 3398 if (gl && gl.getError() == 1286) 3399 handleWebGLError1286(); 3400 } 3401 3402 // If there is no WebGL, fall back to CSS 3D transform renderer. 3403 // This will discard the image loaded so far and load the fallback image. 3404 // While browser specific tests are usually frowned upon, the 3405 // fallback viewer only really works with WebKit/Blink and IE 10/11 3406 // (it doesn't work properly in Firefox). 3407 if (!gl && ((imageType == 'multires' && image.hasOwnProperty('fallbackPath')) || 3408 imageType == 'cubemap') && 3409 ('WebkitAppearance' in document.documentElement.style || 3410 navigator.userAgent.match(/Trident.*rv[ :]*11\./) || 3411 navigator.appVersion.indexOf('MSIE 10') !== -1)) { 3412 // Remove old world if it exists 3413 if (world) { 3414 container.removeChild(world); 3415 } 3416 3417 // Initialize renderer 3418 world = document.createElement('div'); 3419 world.className = 'pnlm-world'; 3420 3421 // Add images 3422 var path; 3423 if (image.basePath) { 3424 path = image.basePath + image.fallbackPath; 3425 } else { 3426 path = image.fallbackPath; 3427 } 3428 var sides = ['f', 'r', 'b', 'l', 'u', 'd']; 3429 var loaded = 0; 3430 var onLoad = function() { 3431 // Draw image on canvas 3432 var faceCanvas = document.createElement('canvas'); 3433 faceCanvas.className = 'pnlm-face pnlm-' + sides[this.side] + 'face'; 3434 world.appendChild(faceCanvas); 3435 var faceContext = faceCanvas.getContext('2d'); 3436 faceCanvas.style.width = this.width + 4 + 'px'; 3437 faceCanvas.style.height = this.height + 4 + 'px'; 3438 faceCanvas.width = this.width + 4; 3439 faceCanvas.height = this.height + 4; 3440 faceContext.drawImage(this, 2, 2); 3441 var imgData = faceContext.getImageData(0, 0, faceCanvas.width, faceCanvas.height); 3442 var data = imgData.data; 3443 3444 // Duplicate edge pixels 3445 var i; 3446 var j; 3447 for (i = 2; i < faceCanvas.width - 2; i++) { 3448 for (j = 0; j < 4; j++) { 3449 data[(i + faceCanvas.width) * 4 + j] = data[(i + faceCanvas.width * 2) * 4 + j]; 3450 data[(i + faceCanvas.width * (faceCanvas.height - 2)) * 4 + j] = data[(i + faceCanvas.width * (faceCanvas.height - 3)) * 4 + j]; 3451 } 3452 } 3453 for (i = 2; i < faceCanvas.height - 2; i++) { 3454 for (j = 0; j < 4; j++) { 3455 data[(i * faceCanvas.width + 1) * 4 + j] = data[(i * faceCanvas.width + 2) * 4 + j]; 3456 data[((i + 1) * faceCanvas.width - 2) * 4 + j] = data[((i + 1) * faceCanvas.width - 3) * 4 + j]; 3457 } 3458 } 3459 for (j = 0; j < 4; j++) { 3460 data[(faceCanvas.width + 1) * 4 + j] = data[(faceCanvas.width * 2 + 2) * 4 + j]; 3461 data[(faceCanvas.width * 2 - 2) * 4 + j] = data[(faceCanvas.width * 3 - 3) * 4 + j]; 3462 data[(faceCanvas.width * (faceCanvas.height - 2) + 1) * 4 + j] = data[(faceCanvas.width * (faceCanvas.height - 3) + 2) * 4 + j]; 3463 data[(faceCanvas.width * (faceCanvas.height - 1) - 2) * 4 + j] = data[(faceCanvas.width * (faceCanvas.height - 2) - 3) * 4 + j]; 3464 } 3465 for (i = 1; i < faceCanvas.width - 1; i++) { 3466 for (j = 0; j < 4; j++) { 3467 data[i * 4 + j] = data[(i + faceCanvas.width) * 4 + j]; 3468 data[(i + faceCanvas.width * (faceCanvas.height - 1)) * 4 + j] = data[(i + faceCanvas.width * (faceCanvas.height - 2)) * 4 + j]; 3469 } 3470 } 3471 for (i = 1; i < faceCanvas.height - 1; i++) { 3472 for (j = 0; j < 4; j++) { 3473 data[(i * faceCanvas.width) * 4 + j] = data[(i * faceCanvas.width + 1) * 4 + j]; 3474 data[((i + 1) * faceCanvas.width - 1) * 4 + j] = data[((i + 1) * faceCanvas.width - 2) * 4 + j]; 3475 } 3476 } 3477 for (j = 0; j < 4; j++) { 3478 data[j] = data[(faceCanvas.width + 1) * 4 + j]; 3479 data[(faceCanvas.width - 1) * 4 + j] = data[(faceCanvas.width * 2 - 2) * 4 + j]; 3480 data[(faceCanvas.width * (faceCanvas.height - 1)) * 4 + j] = data[(faceCanvas.width * (faceCanvas.height - 2) + 1) * 4 + j]; 3481 data[(faceCanvas.width * faceCanvas.height - 1) * 4 + j] = data[(faceCanvas.width * (faceCanvas.height - 1) - 2) * 4 + j]; 3482 } 3483 3484 // Draw image width duplicated edge pixels on canvas 3485 faceContext.putImageData(imgData, 0, 0); 3486 3487 incLoaded.call(this); 3488 }; 3489 var incLoaded = function() { 3490 if (this.width > 0) { 3491 if (fallbackImgSize === undefined) 3492 fallbackImgSize = this.width; 3493 if (fallbackImgSize != this.width) 3494 console.log('Fallback faces have inconsistent widths: ' + fallbackImgSize + ' vs. ' + this.width); 3495 } else 3496 faceMissing = true; 3497 loaded++; 3498 if (loaded == 6) { 3499 fallbackImgSize = this.width; 3500 container.appendChild(world); 3501 callback(); 3502 } 3503 }; 3504 faceMissing = false;
3505 for (s = 0; s < 6; s++) { 3506 var faceImg = new Image(); 3507 faceImg.crossOrigin = globalParams.crossOrigin ? globalParams.crossOrigin : 'anonymous'; 3508 faceImg.side = s; 3509 faceImg.onload = onLoad; 3510 faceImg.onerror = incLoaded; // ignore missing face to support partial fallback image 3511 if (imageType == 'multires') { 3512 faceImg.src = path.replace('%s', sides[s]) + '.' + image.extension; 3513 } else { 3514 faceImg.src = image[s].src; 3515 } 3516 } 3517 fillMissingFaces(fallbackImgSize); 3518 return; 3519 } else if (!gl) { 3520 console.log('Error: no WebGL support detected!'); 3521 throw {type: 'no webgl'}; 3522 } 3523 if (imageType == 'cubemap') 3524 fillMissingFaces(cubeImgWidth); 3525 if (image.basePath) { 3526 image.fullpath = image.basePath + image.path; 3527 } else { 3528 image.fullpath = image.path; 3529 } 3530 image.invTileResolution = 1 / image.tileResolution; 3531 3532 var vertices = createCube(); 3533 vtmps = []; 3534 for (s = 0; s < 6; s++) { 3535 vtmps[s] = vertices.slice(s * 12, s * 12 + 12); 3536 vertices = createCube(); 3537 } 3538 3539 // Make sure image isn't too big 3540 var maxWidth = 0; 3541 if (imageType == 'equirectangular') { 3542 maxWidth = gl.getParameter(gl.MAX_TEXTURE_SIZE); 3543 if (Math.max(image.width / 2, image.height) > maxWidth) { 3544 console.log('Error: The image is too big; it\'s ' + image.width + 'px wide, '+ 3545 'but this device\'s maximum supported size is ' + (maxWidth * 2) + 'px.'); 3546 throw {type: 'webgl size error', width: image.width, maxWidth: maxWidth * 2}; 3547 } 3548 } else if (imageType == 'cubemap') { 3549 if (cubeImgWidth > gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)) { 3550 console.log('Error: The image is too big; it\'s ' + cubeImgWidth + 'px wide, ' + 3551 'but this device\'s maximum supported size is ' + maxWidth + 'px.'); 3552 throw {type: 'webgl size error', width: cubeImgWidth, maxWidth: maxWidth}; 3553 } 3554 } 3555 3556 // Store horizon pitch and roll if applicable 3557 if (params !== undefined && (params.horizonPitch !== undefined || params.horizonRoll !== undefined)) 3558 pose = [params.horizonPitch == undefined ? 0 : params.horizonPitch, 3559 params.horizonRoll == undefined ? 0 : params.horizonRoll]; 3560 3561 // Set 2d texture binding 3562 var glBindType = gl.TEXTURE_2D; 3563 3564 // Create viewport for entire canvas 3565 gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 3566 3567 // Check precision support 3568 if (gl.getShaderPrecisionFormat) { 3569 var precision = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); 3570 if (precision && precision.precision < 1) { 3571 // `highp` precision not supported; https://stackoverflow.com/a/33308927 3572 fragEquiCubeBase = fragEquiCubeBase.replace('highp', 'mediump'); 3573 } 3574 } 3575 3576 // Create vertex shader 3577 vs = gl.createShader(gl.VERTEX_SHADER); 3578 var vertexSrc = v; 3579 if (imageType == 'multires') { 3580 vertexSrc = vMulti; 3581 } 3582 gl.shaderSource(vs, vertexSrc); 3583 gl.compileShader(vs); 3584 3585 // Create fragment shader 3586 fs = gl.createShader(gl.FRAGMENT_SHADER); 3587 var fragmentSrc = fragEquirectangular; 3588 if (imageType == 'cubemap') { 3589 glBindType = gl.TEXTURE_CUBE_MAP; 3590 fragmentSrc = fragCube; 3591 } else if (imageType == 'multires') { 3592 fragmentSrc = fragMulti; 3593 } 3594 gl.shaderSource(fs, fragmentSrc); 3595 gl.compileShader(fs); 3596 3597 // Link WebGL program 3598 program = gl.createProgram(); 3599 gl.attachShader(program, vs); 3600 gl.attachShader(program, fs); 3601 gl.linkProgram(program); 3602 3603 // Log errors 3604 if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) 3605 console.log(gl.getShaderInfoLog(vs)); 3606 if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) 3607 console.log(gl.getShaderInfoLog(fs)); 3608 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) 3609 console.log(gl.getProgramInfoLog(program)); 3610 3611 // Use WebGL program 3612 gl.useProgram(program); 3613 3614 program.drawInProgress = false;
3615 3616 // Set background clear color (does not apply to cubemap/fallback image) 3617 var color = params.backgroundColor ? params.backgroundColor : [0, 0, 0]; 3618 gl.clearColor(color[0], color[1], color[2], 1.0); 3619 gl.clear(gl.COLOR_BUFFER_BIT); 3620 3621 // Look up texture coordinates location 3622 program.texCoordLocation = gl.getAttribLocation(program, 'a_texCoord'); 3623 gl.enableVertexAttribArray(program.texCoordLocation); 3624 3625 if (imageType != 'multires') { 3626 // Provide texture coordinates for rectangle 3627 if (!texCoordBuffer) 3628 texCoordBuffer = gl.createBuffer(); 3629 gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); 3630 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,1,1,1,1,-1,-1,1,1,-1,-1,-1]), gl.STATIC_DRAW); 3631 gl.vertexAttribPointer(program.texCoordLocation, 2, gl.FLOAT, false, 0, 0); 3632 3633 // Pass aspect ratio 3634 program.aspectRatio = gl.getUniformLocation(program, 'u_aspectRatio'); 3635 gl.uniform1f(program.aspectRatio, gl.drawingBufferWidth / gl.drawingBufferHeight); 3636 3637 // Locate psi, theta, focal length, horizontal extent, vertical extent, and vertical offset 3638 program.psi = gl.getUniformLocation(program, 'u_psi'); 3639 program.theta = gl.getUniformLocation(program, 'u_theta'); 3640 program.f = gl.getUniformLocation(program, 'u_f'); 3641 program.h = gl.getUniformLocation(program, 'u_h'); 3642 program.v = gl.getUniformLocation(program, 'u_v'); 3643 program.vo = gl.getUniformLocation(program, 'u_vo'); 3644 program.rot = gl.getUniformLocation(program, 'u_rot'); 3645 3646 // Pass horizontal extent, vertical extent, and vertical offset 3647 gl.uniform1f(program.h, haov / (Math.PI * 2.0)); 3648 gl.uniform1f(program.v, vaov / Math.PI); 3649 gl.uniform1f(program.vo, voffset / Math.PI * 2); 3650 3651 // Set background color 3652 if (imageType == 'equirectangular') { 3653 program.backgroundColor = gl.getUniformLocation(program, 'u_backgroundColor'); 3654 gl.uniform4fv(program.backgroundColor, color.concat([1])); 3655 } 3656 3657 // Create texture 3658 program.texture = gl.createTexture(); 3659 gl.bindTexture(glBindType, program.texture); 3660 3661 // Upload images to texture depending on type 3662 if (imageType == 'cubemap') { 3663 // Load all six sides of the cube map 3664 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[1]); 3665 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[3]); 3666 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[4]); 3667 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[5]); 3668 gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[0]); 3669 gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image[2]); 3670 } else { 3671 if (image.width <= maxWidth) { 3672 gl.uniform1i(gl.getUniformLocation(program, 'u_splitImage'), 0); 3673 // Upload image to the texture 3674 gl.texImage2D(glBindType, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); 3675 } else { 3676 // Image needs to be split into two parts due to texture size limits 3677 gl.uniform1i(gl.getUniformLocation(program, 'u_splitImage'), 1); 3678 3679 // Draw image on canvas 3680 var cropCanvas = document.createElement('canvas'); 3681 cropCanvas.width = image.width / 2; 3682 cropCanvas.height = image.height; 3683 var cropContext = cropCanvas.getContext('2d'); 3684 cropContext.drawImage(image, 0, 0); 3685 3686 // Upload first half of image to the texture 3687 var cropImage = cropContext.getImageData(0, 0, image.width / 2, image.height); 3688 gl.texImage2D(glBindType, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, cropImage); 3689 3690 // Create and bind texture for second half of image 3691 program.texture2 = gl.createTexture(); 3692 gl.activeTexture(gl.TEXTURE1); 3693 gl.bindTexture(glBindType, program.texture2); 3694 gl.uniform1i(gl.getUniformLocation(program, 'u_image1'), 1); 3695 3696 // Upload second half of image to the texture
3697 cropContext.drawImage(image, -image.width / 2, 0); 3698 cropImage = cropContext.getImageData(0, 0, image.width / 2, image.height); 3699 gl.texImage2D(glBindType, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, cropImage); 3700 3701 // Set parameters for rendering any size 3702 gl.texParameteri(glBindType, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 3703 gl.texParameteri(glBindType, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 3704 gl.texParameteri(glBindType, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 3705 gl.texParameteri(glBindType, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 3706 3707 // Reactivate first texture unit 3708 gl.activeTexture(gl.TEXTURE0); 3709 } 3710 } 3711 3712 // Set parameters for rendering any size 3713 gl.texParameteri(glBindType, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 3714 gl.texParameteri(glBindType, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 3715 gl.texParameteri(glBindType, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 3716 gl.texParameteri(glBindType, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 3717 3718 } else { 3719 // Look up vertex coordinates location 3720 program.vertPosLocation = gl.getAttribLocation(program, 'a_vertCoord'); 3721 gl.enableVertexAttribArray(program.vertPosLocation); 3722 3723 // Create buffers 3724 if (!cubeVertBuf) 3725 cubeVertBuf = gl.createBuffer(); 3726 if (!cubeVertTexCoordBuf) 3727 cubeVertTexCoordBuf = gl.createBuffer(); 3728 if (!cubeVertIndBuf) 3729 cubeVertIndBuf = gl.createBuffer(); 3730 3731 // Bind texture coordinate buffer and pass coordinates to WebGL 3732 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertTexCoordBuf); 3733 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0,1,0,1,1,0,1]), gl.STATIC_DRAW); 3734 3735 // Bind square index buffer and pass indicies to WebGL 3736 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertIndBuf); 3737 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0,1,2,0,2,3]), gl.STATIC_DRAW); 3738 3739 // Find uniforms 3740 program.perspUniform = gl.getUniformLocation(program, 'u_perspMatrix'); 3741 program.cubeUniform = gl.getUniformLocation(program, 'u_cubeMatrix'); 3742 //program.colorUniform = gl.getUniformLocation(program, 'u_color'); 3743 3744 program.level = -1; 3745 3746 program.currentNodes = []; 3747 program.nodeCache = []; 3748 program.nodeCacheTimestamp = 0; 3749 } 3750 3751 // Check if there was an error 3752 var err = gl.getError(); 3753 if (err !== 0) { 3754 console.log('Error: Something went wrong with WebGL!', err); 3755 throw {type: 'webgl error'}; 3756 } 3757 3758 callback(); 3759 }; 3760 3761 /** 3762 * Destroy renderer. 3763 * @memberof Renderer 3764 * @instance 3765 */ 3766 this.destroy = function() { 3767 if (container !== undefined) { 3768 if (canvas !== undefined && container.contains(canvas)) { 3769 container.removeChild(canvas); 3770 } 3771 if (world !== undefined && container.contains(world)) { 3772 container.removeChild(world); 3773 } 3774 } 3775 if (gl) { 3776 // The spec says this is only supposed to simulate losing the WebGL 3777 // context, but in practice it tends to actually free the memory. 3778 var extension = gl.getExtension('WEBGL_lose_context'); 3779 if (extension) 3780 extension.loseContext(); 3781 } 3782 }; 3783 3784 /** 3785 * Resize renderer (call after resizing container). 3786 * @memberof Renderer 3787 * @instance 3788 */ 3789 this.resize = function() { 3790 var pixelRatio = window.devicePixelRatio || 1; 3791 canvas.width = canvas.clientWidth * pixelRatio; 3792 canvas.height = canvas.clientHeight * pixelRatio; 3793 if (gl) { 3794 if (gl.getError() == 1286) 3795 handleWebGLError1286(); 3796 gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 3797 if (imageType != 'multires') { 3798 gl.uniform1f(program.aspectRatio, canvas.clientWidth / canvas.clientHeight); 3799 } 3800 } 3801 }; 3802 // Initialize canvas size 3803 this.resize(); 3804 3805 /** 3806 * Set renderer horizon pitch and roll. 3807 * @memberof Renderer 3808 * @instance 3809 */ 3810 this.setPose = function(horizonPitch, horizonRoll) { 3811 pose = [horizonPitch, horizonRoll]; 3812 }; 3813 3814 /**
3815 * Render new view of panorama. 3816 * @memberof Renderer 3817 * @instance 3818 * @param {number} pitch - Pitch to render at (in radians). 3819 * @param {number} yaw - Yaw to render at (in radians). 3820 * @param {number} hfov - Horizontal field of view to render with (in radians). 3821 * @param {Object} [params] - Extra configuration parameters. 3822 * @param {number} [params.roll] - Camera roll (in radians). 3823 * @param {boolean} [params.returnImage] - Return rendered image? 3824 */ 3825 this.render = function(pitch, yaw, hfov, params) { 3826 var focal, i, s, roll = 0; 3827 if (params === undefined) 3828 params = {}; 3829 if (params.roll) 3830 roll = params.roll; 3831 3832 // Apply pitch and roll transformation if applicable 3833 if (pose !== undefined) { 3834 var horizonPitch = pose[0], 3835 horizonRoll = pose[1]; 3836 3837 // Calculate new pitch and yaw 3838 var orig_pitch = pitch, 3839 orig_yaw = yaw, 3840 x = Math.cos(horizonRoll) * Math.sin(pitch) * Math.sin(horizonPitch) + 3841 Math.cos(pitch) * (Math.cos(horizonPitch) * Math.cos(yaw) + 3842 Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.sin(yaw)), 3843 y = -Math.sin(pitch) * Math.sin(horizonRoll) + 3844 Math.cos(pitch) * Math.cos(horizonRoll) * Math.sin(yaw), 3845 z = Math.cos(horizonRoll) * Math.cos(horizonPitch) * Math.sin(pitch) + 3846 Math.cos(pitch) * (-Math.cos(yaw) * Math.sin(horizonPitch) + 3847 Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.sin(yaw)); 3848 pitch = Math.asin(Math.max(Math.min(z, 1), -1)); 3849 yaw = Math.atan2(y, x); 3850 3851 // Calculate roll 3852 var v = [Math.cos(orig_pitch) * (Math.sin(horizonRoll) * Math.sin(horizonPitch) * Math.cos(orig_yaw) - 3853 Math.cos(horizonPitch) * Math.sin(orig_yaw)), 3854 Math.cos(orig_pitch) * Math.cos(horizonRoll) * Math.cos(orig_yaw), 3855 Math.cos(orig_pitch) * (Math.cos(horizonPitch) * Math.sin(horizonRoll) * Math.cos(orig_yaw) + 3856 Math.sin(orig_yaw) * Math.sin(horizonPitch))], 3857 w = [-Math.cos(pitch) * Math.sin(yaw), Math.cos(pitch) * Math.cos(yaw)]; 3858 var roll_adj = Math.acos(Math.max(Math.min((v[0]*w[0] + v[1]*w[1]) / 3859 (Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) * 3860 Math.sqrt(w[0]*w[0]+w[1]*w[1])), 1), -1)); 3861 if (v[2] < 0) 3862 roll_adj = 2 * Math.PI - roll_adj; 3863 roll += roll_adj; 3864 } 3865 3866 // If no WebGL 3867 if (!gl && (imageType == 'multires' || imageType == 'cubemap')) { 3868 // Determine face transforms 3869 s = fallbackImgSize / 2; 3870 3871 var transforms = { 3872 f: 'translate3d(-' + (s + 2) + 'px, -' + (s + 2) + 'px, -' + s + 'px)', 3873 b: 'translate3d(' + (s + 2) + 'px, -' + (s + 2) + 'px, ' + s + 'px) rotateX(180deg) rotateZ(180deg)', 3874 u: 'translate3d(-' + (s + 2) + 'px, -' + s + 'px, ' + (s + 2) + 'px) rotateX(270deg)', 3875 d: 'translate3d(-' + (s + 2) + 'px, ' + s + 'px, -' + (s + 2) + 'px) rotateX(90deg)', 3876 l: 'translate3d(-' + s + 'px, -' + (s + 2) + 'px, ' + (s + 2) + 'px) rotateX(180deg) rotateY(90deg) rotateZ(180deg)', 3877 r: 'translate3d(' + s + 'px, -' + (s + 2) + 'px, -' + (s + 2) + 'px) rotateY(270deg)' 3878 }; 3879 focal = 1 / Math.tan(hfov / 2); 3880 var zoom = focal * canvas.clientWidth / 2 + 'px'; 3881 var transform = 'perspective(' + zoom + ') translateZ(' + zoom + ') rotateX(' + pitch + 'rad) rotateY(' + yaw + 'rad) '; 3882 3883 // Apply face transforms 3884 var faces = Object.keys(transforms); 3885 for (i = 0; i < 6; i++) { 3886 var face = world.querySelector('.pnlm-' + faces[i] + 'face'); 3887 if (!face) 3888 continue; // ignore missing face to support partial cubemap/fallback image 3889 face.style.webkitTransform = transform + transforms[faces[i]]; 3890 face.style.transform = transform + transforms[faces[i]]; 3891 } 3892 return; 3893 } 3894 3895 if (imageType != 'multires') { 3896 // Calculate focal length from vertical field of view 3897 var vfov = 2 * Math.atan(Math.tan(hfov * 0.5) / (gl.drawingBufferWidth / gl.drawingBufferHeight)); 3898 focal = 1 / Math.tan(vfov * 0.5); 3899 3900 // Pass psi, theta, roll, and focal length 3901 gl.uniform1f(program.psi, yaw); 3902 gl.uniform1f(program.theta, pitch); 3903 gl.uniform1f(program.rot, roll); 3904 gl.uniform1f(program.f, focal); 3905 3906 if (dynamic === true) { 3907 // Update texture if dynamic 3908 if (imageType == 'equirectangular') { 3909 gl.bindTexture(gl.TEXTURE_2D, program.texture); 3910 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); 3911 } 3912 } 3913 3914 // Draw using current buffer 3915 gl.drawArrays(gl.TRIANGLES, 0, 6); 3916 3917 } else { 3918 // Create perspective matrix 3919 var perspMatrix = makePersp(hfov, gl.drawingBufferWidth / gl.drawingBufferHeight, 0.1, 100.0); 3920 3921 // Find correct zoom level 3922 checkZoom(hfov); 3923 3924 // Create rotation matrix 3925 var matrix = identityMatrix3(); 3926 matrix = rotateMatrix(matrix, -roll, 'z'); 3927 matrix = rotateMatrix(matrix, -pitch, 'x'); 3928 matrix = rotateMatrix(matrix, yaw, 'y'); 3929 matrix = makeMatrix4(matrix); 3930 3931 // Set matrix uniforms 3932 gl.uniformMatrix4fv(program.perspUniform, false, new Float32Array(trans
vendor: 16,328 bytes, lines 3932-4334
3932poseMatrix4(perspMatrix))); 3933 gl.uniformMatrix4fv(program.cubeUniform, false, new Float32Array(transposeMatrix4(matrix))); 3934 3935 // Find current nodes 3936 var rotPersp = rotatePersp(perspMatrix, matrix); 3937 program.nodeCache.sort(multiresNodeSort); 3938 if (program.nodeCache.length > 200 && 3939 program.nodeCache.length > program.currentNodes.length + 50) { 3940 // Remove older nodes from cache 3941 var removed = program.nodeCache.splice(200, program.nodeCache.length - 200); 3942 for (var j = 0; j < removed.length; j++) { 3943 // Explicitly delete textures 3944 gl.deleteTexture(removed[j].texture); 3945 } 3946 } 3947 program.currentNodes = []; 3948 3949 var sides = ['f', 'b', 'u', 'd', 'l', 'r']; 3950 for (s = 0; s < 6; s++) { 3951 var ntmp = new MultiresNode(vtmps[s], sides[s], 1, 0, 0, image.fullpath); 3952 testMultiresNode(rotPersp, ntmp, pitch, yaw, hfov); 3953 } 3954 3955 program.currentNodes.sort(multiresNodeRenderSort); 3956 3957 // Unqueue any pending requests for nodes that are no longer visible 3958 for (i = pendingTextureRequests.length - 1; i >= 0; i--) { 3959 if (program.currentNodes.indexOf(pendingTextureRequests[i].node) === -1) { 3960 pendingTextureRequests[i].node.textureLoad = false; 3961 pendingTextureRequests.splice(i, 1); 3962 } 3963 } 3964 3965 // Allow one request to be pending, so that we can create a texture buffer for that in advance of loading actually beginning 3966 if (pendingTextureRequests.length === 0) { 3967 for (i = 0; i < program.currentNodes.length; i++) { 3968 var node = program.currentNodes[i]; 3969 if (!node.texture && !node.textureLoad) { 3970 node.textureLoad = true; 3971 3972 setTimeout(processNextTile, 0, node); 3973 3974 // Only process one tile per frame to improve responsiveness 3975 break; 3976 } 3977 } 3978 } 3979 3980 // Draw tiles 3981 multiresDraw(); 3982 } 3983 3984 if (params.returnImage !== undefined) { 3985 return canvas.toDataURL('image/png'); 3986 } 3987 }; 3988 3989 /** 3990 * Check if images are loading. 3991 * @memberof Renderer 3992 * @instance 3993 * @returns {boolean} Whether or not images are loading. 3994 */ 3995 this.isLoading = function() { 3996 if (gl && imageType == 'multires') { 3997 for ( var i = 0; i < program.currentNodes.length; i++ ) { 3998 if (!program.currentNodes[i].textureLoaded) { 3999 return true; 4000 } 4001 } 4002 } 4003 return false; 4004 }; 4005 4006 /** 4007 * Retrieve renderer's canvas. 4008 * @memberof Renderer 4009 * @instance 4010 * @returns {HTMLElement} Renderer's canvas. 4011 */ 4012 this.getCanvas = function() { 4013 return canvas; 4014 }; 4015 4016 /** 4017 * Sorting method for multires nodes. 4018 * @private 4019 * @param {MultiresNode} a - First node. 4020 * @param {MultiresNode} b - Second node. 4021 * @returns {number} Base tiles first, then higher timestamp first. 4022 */ 4023 function multiresNodeSort(a, b) { 4024 // Base tiles are always first 4025 if (a.level == 1 && b.level != 1) { 4026 return -1; 4027 } 4028 if (b. level == 1 && a.level != 1) { 4029 return 1; 4030 } 4031 4032 // Higher timestamp first 4033 return b.timestamp - a.timestamp; 4034 } 4035 4036 /** 4037 * Sorting method for multires node rendering. 4038 * @private 4039 * @param {MultiresNode} a - First node. 4040 * @param {MultiresNode} b - Second node. 4041 * @returns {number} Lower zoom levels first, then closest to center first. 4042 */ 4043 function multiresNodeRenderSort(a, b) { 4044 // Lower zoom levels first 4045 if (a.level != b.level) { 4046 return a.level - b.level; 4047 } 4048 4049 // Lower distance from center first 4050 return a.diff - b.diff; 4051 } 4052 4053 /** 4054 * Draws multires nodes. 4055 * @private 4056 */ 4057 function multiresDraw() { 4058 if (!program.drawInProgress) { 4059 program.drawInProgress = true; 4060 gl.clear(gl.COLOR_BUFFER_BIT); 4061 for ( var i = 0; i < program.currentNodes.length; i++ ) { 4062 if (program.currentNodes[i].textureLoaded > 1) { 4063 //var color = program.currentNodes[i].color; 4064 //gl.uniform4f(program.colorUniform, color[0], color[1], color[2], 1.0); 4065 4066 // Bind vertex buffer and pass vertices to WebGL 4067 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertBuf); 4068 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(program.currentNodes[i].vertices), gl.STATIC_DRAW); 4069 gl.vertexAttribPointer(program.vertPosLocation, 3, gl.FLOAT, false, 0, 0); 4070 4071 // Prep for texture 4072 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertTexCoordBuf); 4073 gl.vertexAttribPointer(program.texCoordLocation, 2, gl.FLOAT, false, 0, 0); 4074 4075 // Bind texture and draw tile 4076 gl.bindTexture(gl.TEXTURE_2D, program.currentNodes[i].texture); // Bind program.currentNodes[i].texture to TEXTURE0 4077 gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 4078 } 4079 } 4080 program.drawInProgress = false; 4081 } 4082 } 4083 4084 /** 4085 * Creates new multires node. 4086 * @constructor 4087 * @private 4088 * @param {number[]} vertices - Node's verticies. 4089 * @param {string} side - Node's cube face. 4090 * @param {number} level - Node's zoom level. 4091 * @param {number} x - Node's x position. 4092 * @param {number} y - Node's y position. 4093 * @param {string} path - Node's path. 4094 */ 4095 function MultiresNode(vertices, side, level, x, y, path) { 4096 this.vertices = vertices; 4097 this.side = side; 4098 this.level = level; 4099 this.x = x; 4100 this.y = y; 4101 this.path = path.replace('%s',side).replace('%l',level).replace('%x',x).replace('%y',y); 4102 } 4103 4104 /** 4105 * Test if multires node is visible. If it is, add it to current nodes, 4106 * load its texture, and load appropriate child nodes. 4107 * @private 4108 * @param {number[]} rotPersp - Rotated perspective matrix. 4109 * @param {MultiresNode} node - Multires node to check. 4110 * @param {number} pitch - Pitch to check at. 4111 * @param {number} yaw - Yaw to check at. 4112 * @param {number} hfov - Horizontal field of view to check at. 4113 */ 4114 function testMultiresNode(rotPersp, node, pitch, yaw, hfov) { 4115 if (checkSquareInView(rotPersp, node.vertices)) { 4116 // Calculate central angle between center of view and center of tile 4117 var v = node.vertices; 4118 var x = v[0] + v[3] + v[6] + v[ 9]; 4119 var y = v[1] + v[4] + v[7] + v[10]; 4120 var z = v[2] + v[5] + v[8] + v[11]; 4121 var r = Math.sqrt(x*x + y*y + z*z); 4122 var theta = Math.asin(z / r); 4123 var phi = Math.atan2(y, x); 4124 var ydiff = phi - yaw; 4125 ydiff += (ydiff > Math.PI) ? -2 * Math.PI : (ydiff < -Math.PI) ? 2 * Math.PI : 0; 4126 ydiff = Math.abs(ydiff); 4127 node.diff = Math.acos(Math.sin(pitch) * Math.sin(theta) + Math.cos(pitch) * Math.cos(theta) * Math.cos(ydiff)); 4128 4129 // Add node to current nodes and load texture if needed 4130 var inCurrent = false; 4131 for (var k = 0; k < program.nodeCache.length; k++) { 4132 if (program.nodeCache[k].path == node.path) { 4133 inCurrent = true; 4134 program.nodeCache[k].timestamp = program.nodeCacheTimestamp++; 4135 program.nodeCache[k].diff = node.diff; 4136 program.currentNodes.push(program.nodeCache[k]); 4137 break; 4138 } 4139 } 4140 if (!inCurrent) { 4141 //node.color = [Math.random(), Math.random(), Math.random()]; 4142 node.timestamp = program.nodeCacheTimestamp++; 4143 program.currentNodes.push(node); 4144 program.nodeCache.push(node); 4145 } 4146 4147 // TODO: Test error 4148 // Create child nodes 4149 if (node.level < program.level) { 4150 var cubeSize = image.cubeResolution * Math.pow(2, node.level - image.maxLevel); 4151 var numTiles = Math.ceil(cubeSize * image.invTileResolution) - 1; 4152 var doubleTileSize = cubeSize % image.tileResolution * 2; 4153 var lastTileSize = (cubeSize * 2) % image.tileResolution; 4154 if (lastTileSize === 0) { 4155 lastTileSize = image.tileResolution; 4156 } 4157 if (doubleTileSize === 0) { 4158 doubleTileSize = image.tileResolution * 2; 4159 } 4160 var f = 0.5; 4161 if (node.x == numTiles || node.y == numTiles) { 4162 f = 1.0 - image.tileResolution / (image.tileResolution + lastTileSize); 4163 } 4164 var i = 1.0 - f; 4165 var children = []; 4166 var vtmp, ntmp; 4167 var f1 = f, f2 = f, f3 = f, i1 = i, i2 = i, i3 = i; 4168 // Handle non-symmetric tiles 4169 if (lastTileSize < image.tileResolution) { 4170 if (node.x == numTiles && node.y != numTiles) { 4171 f2 = 0.5; 4172 i2 = 0.5; 4173 if (node.side == 'd' || node.side == 'u') { 4174 f3 = 0.5; 4175 i3 = 0.5; 4176 } 4177 } else if (node.x != numTiles && node.y == numTiles) { 4178 f1 = 0.5; 4179 i1 = 0.5; 4180 if (node.side == 'l' || node.side == 'r') { 4181 f3 = 0.5; 4182 i3 = 0.5; 4183 } 4184 } 4185 } 4186 // Handle small tiles that have fewer than four children 4187 if (doubleTileSize <= image.tileResolution) { 4188 if (node.x == numTiles) { 4189 f1 = 0; 4190 i1 = 1; 4191 if (node.side == 'l' || node.side == 'r') { 4192 f3 = 0; 4193 i3 = 1; 4194 } 4195 } 4196 if (node.y == numTiles) { 4197 f2 = 0; 4198 i2 = 1; 4199 if (node.side == 'd' || node.side == 'u') { 4200 f3 = 0; 4201 i3 = 1; 4202 } 4203 } 4204 } 4205 4206 vtmp = [ v[0], v[1], v[2], 4207 v[0]*f1+v[3]*i1, v[1]*f+v[4]*i, v[2]*f3+v[5]*i3, 4208 v[0]*f1+v[6]*i1, v[1]*f2+v[7]*i2, v[2]*f3+v[8]*i3, 4209 v[0]*f+v[9]*i, v[1]*f2+v[10]*i2, v[2]*f3+v[11]*i3 4210 ]; 4211 ntmp = new MultiresNode(vtmp, node.side, node.level + 1, node.x*2, node.y*2, image.fullpath); 4212 children.push(ntmp); 4213 if (!(node.x == numTiles && doubleTileSize <= image.tileResolution)) { 4214 vtmp = [v[0]*f1+v[3]*i1, v[1]*f+v[4]*i, v[2]*f3+v[5]*i3, 4215 v[3], v[4], v[5], 4216 v[3]*f+v[6]*i, v[4]*f2+v[7]*i2, v[5]*f3+v[8]*i3, 4217 v[0]*f1+v[6]*i1, v[1]*f2+v[7]*i2, v[2]*f3+v[8]*i3 4218 ]; 4219 ntmp = new MultiresNode(vtmp, node.side, node.level + 1, node.x*2+1, node.y*2, image.fullpath); 4220 children.push(ntmp); 4221 } 4222 if (!(node.x == numTiles && doubleTileSize <= image.tileResolution) && 4223 !(node.y == numTiles && doubleTileSize <= image.tileResolution)) { 4224 vtmp = [v[0]*f1+v[6]*i1, v[1]*f2+v[7]*i2, v[2]*f3+v[8]*i3, 4225 v[3]*f+v[6]*i, v[4]*f2+v[7]*i2, v[5]*f3+v[8]*i3, 4226 v[6], v[7], v[8], 4227 v[9]*f1+v[6]*i1, v[10]*f+v[7]*i, v[11]*f3+v[8]*i3 4228 ]; 4229 ntmp = new MultiresNode(vtmp, node.side, node.level + 1, node.x*2+1, node.y*2+1, image.fullpath); 4230 children.push(ntmp); 4231 } 4232 if (!(node.y == numTiles && doubleTileSize <= image.tileResolution)) { 4233 vtmp = [ v[0]*f+v[9]*i, v[1]*f2+v[10]*i2, v[2]*f3+v[11]*i3, 4234 v[0]*f1+v[6]*i1, v[1]*f2+v[7]*i2, v[2]*f3+v[8]*i3, 4235 v[9]*f1+v[6]*i1, v[10]*f+v[7]*i, v[11]*f3+v[8]*i3, 4236 v[9], v[10], v[11] 4237 ]; 4238 ntmp = new MultiresNode(vtmp, node.side, node.level + 1, node.x*2, node.y*2+1, image.fullpath); 4239 children.push(ntmp); 4240 } 4241 for (var j = 0; j < children.length; j++) { 4242 testMultiresNode(rotPersp, children[j], pitch, yaw, hfov); 4243 } 4244 } 4245 } 4246 } 4247 4248 /** 4249 * Creates cube vertex array. 4250 * @private 4251 * @returns {number[]} Cube vertex array. 4252 */ 4253 function createCube() { 4254 return [-1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, // Front face 4255 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // Back face 4256 -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, // Up face 4257 -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // Down face 4258 -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // Left face 4259 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1 // Right face 4260 ]; 4261 } 4262 4263 /** 4264 * Creates 3x3 identity matrix. 4265 * @private 4266 * @returns {number[]} Identity matrix. 4267 */ 4268 function identityMatrix3() { 4269 return [ 4270 1, 0, 0, 4271 0, 1, 0, 4272 0, 0, 1 4273 ]; 4274 } 4275 4276 /** 4277 * Rotates a 3x3 matrix. 4278 * @private 4279 * @param {number[]} m - Matrix to rotate. 4280 * @param {number[]} angle - Angle to rotate by in radians. 4281 * @param {string} axis - Axis to rotate about (`x`, `y`, or `z`). 4282 * @returns {number[]} Rotated matrix. 4283 */ 4284 function rotateMatrix(m, angle, axis) { 4285 var s = Math.sin(angle); 4286 var c = Math.cos(angle); 4287 if (axis == 'x') { 4288 return [ 4289 m[0], c*m[1] + s*m[2], c*m[2] - s*m[1], 4290 m[3], c*m[4] + s*m[5], c*m[5] - s*m[4], 4291 m[6], c*m[7] + s*m[8], c*m[8] - s*m[7] 4292 ]; 4293 } 4294 if (axis == 'y') { 4295 return [ 4296 c*m[0] - s*m[2], m[1], c*m[2] + s*m[0], 4297 c*m[3] - s*m[5], m[4], c*m[5] + s*m[3], 4298 c*m[6] - s*m[8], m[7], c*m[8] + s*m[6] 4299 ]; 4300 } 4301 if (axis == 'z') { 4302 return [ 4303 c*m[0] + s*m[1], c*m[1] - s*m[0], m[2], 4304 c*m[3] + s*m[4], c*m[4] - s*m[3], m[5], 4305 c*m[6] + s*m[7], c*m[7] - s*m[6], m[8] 4306 ]; 4307 } 4308 } 4309 4310 /** 4311 * Turns a 3x3 matrix into a 4x4 matrix. 4312 * @private 4313 * @param {number[]} m - Input matrix. 4314 * @returns {number[]} Expanded matrix. 4315 */ 4316 function makeMatrix4(m) { 4317 return [ 4318 m[0], m[1], m[2], 0, 4319 m[3], m[4], m[5], 0, 4320 m[6], m[7], m[8], 0, 4321 0, 0, 0, 1 4322 ]; 4323 } 4324 4325 /** 4326 * Transposes a 4x4 matrix. 4327 * @private 4328 * @param {number[]} m - Input matrix. 4329 * @returns {number[]} Transposed matrix. 4330 */ 4331 function transposeMatrix4(m) { 4332 return [ 4333 m[ 0], m[ 4], m[ 8], m[12], 4334 m[ 1], m[ 5], m[ 9], m[13],
4335 m[ 2], m[ 6], m[10], m[14], 4336 m[ 3], m[ 7], m[11], m[15] 4337 ]; 4338 } 4339 4340 /** 4341 * Creates a perspective matrix. 4342 * @private 4343 * @param {number} hfov - Desired horizontal field of view. 4344 * @param {number} aspect - Desired aspect ratio. 4345 * @param {number} znear - Near distance. 4346 * @param {number} zfar - Far distance. 4347 * @returns {number[]} Generated perspective matrix. 4348 */ 4349 function makePersp(hfov, aspect, znear, zfar) { 4350 var fovy = 2 * Math.atan(Math.tan(hfov/2) * gl.drawingBufferHeight / gl.drawingBufferWidth); 4351 var f = 1 / Math.tan(fovy/2); 4352 return [ 4353 f/aspect, 0, 0, 0, 4354 0, f, 0, 0, 4355 0, 0, (zfar+znear)/(znear-zfar), (2*zfar*znear)/(znear-zfar), 4356 0, 0, -1, 0 4357 ]; 4358 } 4359 4360 /** 4361 * Processes a loaded texture image into a WebGL texture. 4362 * @private 4363 * @param {Image} img - Input image. 4364 * @param {WebGLTexture} tex - Texture to bind image to. 4365 */ 4366 function processLoadedTexture(img, tex) { 4367 gl.bindTexture(gl.TEXTURE_2D, tex); 4368 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img); 4369 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 4370 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 4371 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 4372 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 4373 gl.bindTexture(gl.TEXTURE_2D, null); 4374 } 4375 4376 var pendingTextureRequests = []; 4377 4378 // Based on http://blog.tojicode.com/2012/03/javascript-memory-optimization-and.html 4379 var loadTexture = (function() { 4380 var cacheTop = 4; // Maximum number of concurrents loads 4381 var textureImageCache = {}; 4382 var crossOrigin; 4383 4384 function TextureImageLoader() { 4385 var self = this; 4386 this.texture = this.callback = null; 4387 this.image = new Image(); 4388 this.image.crossOrigin = crossOrigin ? crossOrigin : 'anonymous'; 4389 var loadFn = (function() { 4390 if (self.image.width > 0 && self.image.height > 0) { // ignore missing tile to supporting partial image 4391 processLoadedTexture(self.image, self.texture); 4392 self.callback(self.texture, true); 4393 } else { 4394 self.callback(self.texture, false); 4395 } 4396 releaseTextureImageLoader(self); 4397 }); 4398 this.image.addEventListener('load', loadFn); 4399 this.image.addEventListener('error', loadFn); // ignore missing tile file to support partial image, otherwise retry loop causes high CPU load 4400 } 4401 4402 TextureImageLoader.prototype.loadTexture = function(src, texture, callback) { 4403 this.texture = texture; 4404 this.callback = callback; 4405 this.image.src = src; 4406 }; 4407 4408 function PendingTextureRequest(node, src, texture, callback) { 4409 this.node = node; 4410 this.src = src; 4411 this.texture = texture; 4412 this.callback = callback; 4413 } 4414 4415 function releaseTextureImageLoader(til) { 4416 if (pendingTextureRequests.length) { 4417 var req = pendingTextureRequests.shift(); 4418 til.loadTexture(req.src, req.texture, req.callback); 4419 } else 4420 textureImageCache[cacheTop++] = til; 4421 } 4422 4423 for (var i = 0; i < cacheTop; i++) 4424 textureImageCache[i] = new TextureImageLoader(); 4425 4426 return function(node, src, callback, _crossOrigin) { 4427 crossOrigin = _crossOrigin; 4428 var texture = gl.createTexture(); 4429 if (cacheTop) 4430 textureImageCache[--cacheTop].loadTexture(src, texture, callback); 4431 else 4432 pendingTextureRequests.push(new PendingTextureRequest(node, src, texture, callback)); 4433 return texture; 4434 }; 4435 })(); 4436 4437 /** 4438 * Loads image and creates texture for a multires node / tile. 4439 * @private 4440 * @param {MultiresNode} node - Input node. 4441 */ 4442 function processNextTile(node) { 4443 loadTexture(node, node.path + '.' + image.extension, function(texture, loaded) { 4444 node.texture = texture; 4445 node.textureLoaded = loaded ? 2 : 1; 4446 }, globalParams.crossOrigin); 4447 } 4448 4449 /** 4450 * Finds and applies optimal multires zoom level. 4451 * @private 4452 * @param {number} hfov - Horizontal field of view to check at. 4453 */ 4454 function checkZoom(hfov) { 4455 // Find optimal level 4456 var newLevel = 1; 4457 while ( newLevel < image.maxLevel && 4458 gl.drawingBufferWidth >
4458 image.tileResolution * 4459 Math.pow(2, newLevel - 1) * Math.tan(hfov / 2) * 0.707 ) { 4460 newLevel++; 4461 } 4462 4463 // Apply change 4464 program.level = newLevel; 4465 } 4466 4467 /** 4468 * Rotates perspective matrix. 4469 * @private 4470 * @param {number[]} p - Perspective matrix. 4471 * @param {number[]} r - Rotation matrix. 4472 * @returns {number[]} Rotated matrix. 4473 */ 4474 function rotatePersp(p, r) { 4475 return [ 4476 p[ 0]*r[0], p[ 0]*r[1], p[ 0]*r[ 2], 0, 4477 p[ 5]*r[4], p[ 5]*r[5], p[ 5]*r[ 6], 0, 4478 p[10]*r[8], p[10]*r[9], p[10]*r[10], p[11], 4479 -r[8], -r[9], -r[10], 0 4480 ]; 4481 } 4482 4483 /** 4484 * Applies rotated perspective matrix to a 3-vector 4485 * (last element is inverted). 4486 * @private 4487 * @param {number[]} m - Rotated perspective matrix. 4488 * @param {number[]} v - Input 3-vector. 4489 * @returns {number[]} Resulting 4-vector. 4490 */ 4491 function applyRotPerspToVec(m, v) { 4492 return [ 4493 m[ 0]*v[0] + m[ 1]*v[1] + m[ 2]*v[2], 4494 m[ 4]*v[0] + m[ 5]*v[1] + m[ 6]*v[2], 4495 m[11] + m[ 8]*v[0] + m[ 9]*v[1] + m[10]*v[2], 4496 1/(m[12]*v[0] + m[13]*v[1] + m[14]*v[2]) 4497 ]; 4498 } 4499 4500 /** 4501 * Checks if a vertex is visible. 4502 * @private 4503 * @param {number[]} m - Rotated perspective matrix. 4504 * @param {number[]} v - Input vertex. 4505 * @returns {number} 1 or -1 if the vertex is or is not visible, 4506 * respectively. 4507 */ 4508 function checkInView(m, v) { 4509 var vpp = applyRotPerspToVec(m, v); 4510 var winX = vpp[0]*vpp[3]; 4511 var winY = vpp[1]*vpp[3]; 4512 var winZ = vpp[2]*vpp[3]; 4513 var ret = [0, 0, 0]; 4514 4515 if ( winX < -1 ) 4516 ret[0] = -1; 4517 if ( winX > 1 ) 4518 ret[0] = 1; 4519 if ( winY < -1 ) 4520 ret[1] = -1; 4521 if ( winY > 1 ) 4522 ret[1] = 1; 4523 if ( winZ < -1 || winZ > 1 ) 4524 ret[2] = 1; 4525 return ret; 4526 } 4527 4528 /** 4529 * Checks if a square (tile) is visible. 4530 * @private 4531 * @param {number[]} m - Rotated perspective matrix. 4532 * @param {number[]} v - Square's vertex array. 4533 * @returns {boolean} Whether or not the square is visible. 4534 */ 4535 function checkSquareInView(m, v) { 4536 var check1 = checkInView(m, v.slice(0, 3)); 4537 var check2 = checkInView(m, v.slice(3, 6)); 4538 var check3 = checkInView(m, v.slice(6, 9)); 4539 var check4 = checkInView(m, v.slice(9, 12)); 4540 var testX = check1[0] + check2[0] + check3[0] + check4[0]; 4541 if ( testX == -4 || testX == 4 ) 4542 return false; 4543 var testY = check1[1] + check2[1] + check3[1] + check4[1]; 4544 if ( testY == -4 || testY == 4 ) 4545 return false; 4546 var testZ = check1[2] + check2[2] + check3[2] + check4[2]; 4547 return testZ != 4; 4548 4549 4550 } 4551 4552 /** 4553 * On iOS (iPhone 5c, iOS 10.3), this WebGL error occurs when the canvas is 4554 * too big. Unfortuately, there's no way to test for this beforehand, so we 4555 * reduce the canvas size if this error is thrown. 4556 * @private 4557 */ 4558 function handleWebGLError1286() { 4559 console.log('Reducing canvas size due to error 1286!'); 4560 canvas.width = Math.round(canvas.width / 2); 4561 canvas.height = Math.round(canvas.height / 2); 4562 } 4563} 4564 4565// Vertex shader for equirectangular and cube 4566var v = [ 4567'attribute vec2 a_texCoord;', 4568'varying vec2 v_texCoord;', 4569 4570'void main() {', 4571 // Set position 4572 'gl_Position = vec4(a_texCoord, 0.0, 1.0);', 4573 4574 // Pass the coordinates to the fragment shader 4575 'v_texCoord = a_texCoord;', 4576'}' 4577].join(''); 4578 4579// Vertex shader for multires 4580var vMulti = [ 4581'attribute vec3 a_vertCoord;', 4582'attribute vec2 a_texCoord;', 4583 4584'uniform mat4 u_cubeMatrix;', 4585'uniform mat4 u_perspMatrix;', 4586 4587'varying mediump vec2 v_texCoord;', 4588 4589'void main(void) {', 4590 // Set position 4591 'gl_Position = u_perspMatrix * u_cubeMatrix * vec4(a_vertCoord, 1.0);', 4592 4593 // Pass the coordinates to the fragment shader 4594 'v_texCoord = a_texCoord;', 4595'}' 4596].join(''); 4597 4598// Fragment shader 4599var fragEquiCubeBase = [ 4600'precision highp float;', // mediump looks bad on some mobile devices 4601 4602'uniform float u_aspectRatio;', 4603'uniform float u_psi;', 4604'uniform float u_theta;', 4605'uniform float u_f;', 4606'uniform float u_h;', 4607'uniform float u_v;', 4608'uniform float u_vo;', 4609'uniform float u_rot;', 4610
4611'const float PI = 3.14159265358979323846264;', 4612 4613// Texture 4614'uniform sampler2D u_image0;', 4615'uniform sampler2D u_image1;', 4616'uniform bool u_splitImage;', 4617'uniform samplerCube u_imageCube;', 4618 4619// Coordinates passed in from vertex shader 4620'varying vec2 v_texCoord;', 4621 4622// Background color (display for partial panoramas) 4623'uniform vec4 u_backgroundColor;', 4624 4625'void main() {', 4626 // Map canvas/camera to sphere 4627 'float x = v_texCoord.x * u_aspectRatio;', 4628 'float y = v_texCoord.y;', 4629 'float sinrot = sin(u_rot);', 4630 'float cosrot = cos(u_rot);', 4631 'float rot_x = x * cosrot - y * sinrot;', 4632 'float rot_y = x * sinrot + y * cosrot;', 4633 'float sintheta = sin(u_theta);', 4634 'float costheta = cos(u_theta);', 4635 'float a = u_f * costheta - rot_y * sintheta;', 4636 'float root = sqrt(rot_x * rot_x + a * a);', 4637 'float lambda = atan(rot_x / root, a / root) + u_psi;', 4638 'float phi = atan((rot_y * costheta + u_f * sintheta) / root);', 4639].join('\n'); 4640 4641// Fragment shader 4642var fragCube = fragEquiCubeBase + [ 4643 // Look up color from texture 4644 'float cosphi = cos(phi);', 4645 'gl_FragColor = textureCube(u_imageCube, vec3(cosphi*sin(lambda), sin(phi), cosphi*cos(lambda)));', 4646'}' 4647].join('\n'); 4648 4649// Fragment shader 4650var fragEquirectangular = fragEquiCubeBase + [ 4651 // Wrap image 4652 'lambda = mod(lambda + PI, PI * 2.0) - PI;', 4653 4654 // Map texture to sphere 4655 'vec2 coord = vec2(lambda / PI, phi / (PI / 2.0));', 4656 4657 // Look up color from texture 4658 // Map from [-1,1] to [0,1] and flip y-axis 4659 'if(coord.x < -u_h || coord.x > u_h || coord.y < -u_v + u_vo || coord.y > u_v + u_vo)', 4660 'gl_FragColor = u_backgroundColor;', 4661 'else {', 4662 'if(u_splitImage) {', 4663 // Image was split into two textures to work around texture size limits 4664 'if(coord.x < 0.0)', 4665 'gl_FragColor = texture2D(u_image0, vec2((coord.x + u_h) / u_h, (-coord.y + u_v + u_vo) / (u_v * 2.0)));', 4666 'else', 4667 'gl_FragColor = texture2D(u_image1, vec2((coord.x + u_h) / u_h - 1.0, (-coord.y + u_v + u_vo) / (u_v * 2.0)));', 4668 '} else {', 4669 'gl_FragColor = texture2D(u_image0, vec2((coord.x + u_h) / (u_h * 2.0), (-coord.y + u_v + u_vo) / (u_v * 2.0)));', 4670 '}', 4671 '}', 4672'}' 4673].join('\n'); 4674 4675// Fragment shader 4676var fragMulti = [ 4677'varying mediump vec2 v_texCoord;', 4678'uniform sampler2D u_sampler;', 4679//'uniform mediump vec4 u_color;', 4680 4681'void main(void) {', 4682 // Look up color from texture 4683 'gl_FragColor = texture2D(u_sampler, v_texCoord);', 4684// 'gl_FragColor = u_color;', 4685'}' 4686].join(''); 4687 4688return { 4689 renderer: function(container, image, imagetype, dynamic) { 4690 return new Renderer(container, image, imagetype, dynamic); 4691 } 4692}; 4693 4694})(window, document); 4695// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/admin/lib/video.js?ver=1 4696/** 4697 * @license 4698 * Video.js 7.18.1 <http://videojs.com/> 4699 * Copyright Brightcove, Inc. <https://www.brightcove.com/> 4700 * Available under Apache License Version 2.0 4701 * <https://github.com/videojs/video.js/blob/main/LICENSE> 4702 * 4703 * Includes vtt.js <https://github.com/mozilla/vtt.js> 4704 * Available under Apache License Version 2.0 4705 * <https://github.com/mozilla/vtt.js/blob/main/LICENSE> 4706 */ 4707 !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojs=t()}(this,function(){"use strict";for(var e,u="7.18.1",i={},a=function(e,t){return i[e]=i[e]||[],t&&(i[e]=i[e].concat(t)),i[e]},n=function(e,t){t=a(e).indexOf(t);return!(t<=-1)&&(i[e]=i[e].slice(),i[e].splice(t,1),!0)},l={prefixed:!0},t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror","fullscreen"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror","-webkit-full-screen"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror","-moz-full-screen"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError","-ms-fullscreen"]],r=t[0],s=0;s<t.length;s++)if(t[s][1]in document){e=t[s];break}if(e){for(var o=0;o<e.length;o++)l[r[o]]=e[o];l.prefixed=e[0]!==r[0]}var c=[],d=function(a,s){return function(e,t,i){var n,r=s.levels[t],t=new RegExp("^("+r+")$");"log"!==e&&i.unshift(e.toUpperCase()+":"),i.unshift(a+":"),c&&(c.push([].concat(i)),n=c.length-1e3,c.splice(0,0<n?n:0)),!window.console||(n=!(n=window.console[e])&&"debug"===e?window.console.info||window.console.log:n)&&r&&t.test(e)&&n[Array.isArray(i)?"apply":"call"](window.console,i)}};var h=function t(i){function n(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];a("log",r,t)}var r="info",a=d(i,n);return n.createLogger=function(e){return t(i+": "+e)},n.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:r},n.level=function(e){if("string"==typeof e){if(!n.levels.hasOwnProperty(e))throw new Error('"'+e+'" in not a valid log level');r=e}return r},(n.history=function(){return c?[].concat(c):[]}).filter=function(t){return(c||[]).filter(function(e){return new RegExp(".*"+t+".*").test(e[0])})},n.history.clear=function(){c&&(c.length=0)},n.history.disable=function(){null!==c&&(c.length=0,c=null)},n.history.enable=function(){null===c&&(c=[])},n.error=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("error",r,t)},n.warn=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("warn",r,t)},n.debug=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("debug",r,t)},n}("VIDEOJS"),p=h.createLogger,f="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function m(e,t){return e(t={exports:{}},t.exports),t.exports}var g=m(function(e){function t(){return e.exports=t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i,n=arguments[t];for(i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e},t.apply(this,arguments)}
4707e.exports=t}),y=Object.prototype.toString,v=function(e){return T(e)?Object.keys(e):[]};function _(t,i){v(t).forEach(function(e){return i(t[e],e)})}function b(i){for(var e=arguments.length,t=new Array(1<e?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];return Object.assign?g.apply(void 0,[i].concat(t)):(t.forEach(function(e){e&&_(e,function(e,t){i[t]=e})}),i)}function T(e){return!!e&&"object"==typeof e}function S(e){return T(e)&&"[object Object]"===y.call(e)&&e.constructor===Object}function w(e,t){if(!e||!t)return"";if("function"!=typeof window.getComputedStyle)return"";var i;try{i=window.getComputedStyle(e)}catch(e){return""}return i?i.getPropertyValue(t)||i[t]:""}var E=window.navigator&&window.navigator.userAgent||"",k=/AppleWebKit\/([\d.]+)/i.exec(E),C=k?parseFloat(k.pop()):null,I=/iPod/i.test(E),x=(jt=E.match(/OS (\d+)_/i))&&jt[1]?jt[1]:null,A=/Android/i.test(E),P=function(){var e=E.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!e)return null;var t=e[1]&&parseFloat(e[1]),i=e[2]&&parseFloat(e[2]);return t&&i?parseFloat(e[1]+"."+e[2]):t||null}(),L=A&&P<5&&C<537,D=/Firefox/i.test(E),O=/Edg/i.test(E),R=!O&&(/Chrome/i.test(E)||/CriOS/i.test(E)),M=(zt=E.match(/(Chrome|CriOS)\/(\d+)/))&&zt[2]?parseFloat(zt[2]):null,N=Xt=!(Xt=(Xt=/MSIE\s(\d+)\.\d/.exec(E))&&parseFloat(Xt[1]))&&/Trident\/7.0/i.test(E)&&/rv:11.0/.test(E)?11:Xt,U=/Safari/i.test(E)&&!R&&!A&&!O,B=/Windows/i.test(E),F=Boolean(X()&&("ontouchstart"in window||window.navigator.maxTouchPoints||window.DocumentTouch&&window.document instanceof window.DocumentTouch)),j=/iPad/i.test(E)||U&&F&&!/iPhone/i.test(E),H=/iPhone/i.test(E)&&!j,q=H||j||I,V=(U||q)&&!R,W=Object.freeze({__proto__:null,IS_IPOD:I,IOS_VERSION:x,IS_ANDROID:A,ANDROID_VERSION:P,IS_NATIVE_ANDROID:L,IS_FIREFOX:D,IS_EDGE:O,IS_CHROME:R,CHROME_VERSION:M,IE_VERSION:N,IS_SAFARI:U,IS_WINDOWS:B,TOUCH_ENABLED:F,IS_IPAD:j,IS_IPHONE:H,IS_IOS:q,IS_ANY_SAFARI:V});function G(e){return"string"==typeof e&&Boolean(e.trim())}function z(e){if(0<=e.indexOf(" "))throw new Error("class has illegal whitespace characters")}function X(){return document===window.document}function K(e){return T(e)&&1===e.nodeType}function Y(){try{return window.parent!==window.self}catch(e){return!0}}function Q(i){return function(e,t){if(!G(e))return document[i](null);t=K(t=G(t)?document.querySelector(t):t)?t:document;return t[i]&&t[i](e)}}function $(e,i,t,n){void 0===e&&(e="div"),void 0===i&&(i={}),void 0===t&&(t={});var r=document.createElement(e);return Object.getOwnPropertyNames(i).forEach(function(e){var t=i[e];-1!==e.indexOf("aria-")||"role"===e||"type"===e?(h.warn("Setting attributes in the second argument of createEl()\nhas been deprecated. Use the third argument instead.\ncreateEl(type, properties, attributes). Attempting to set "+e+" to "+t+"."),r.setAttribute(e,t)):"textContent"===e?J(r,t):r[e]===t&&"tabIndex"!==e||(r[e]=t)}),Object.getOwnPropertyNames(t).forEach(function(e){r.setAttribute(e,t[e])}),n&&ye(r,n),r}function J(e,t){return"undefined"==typeof e.textContent?e.innerText=t:e.textContent=t,e}function Z(e,t){t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e)}function ee(e,t){return z(t),e.classList?e.classList.contains(t):new RegExp("(^|\\s)"+t+"($|\\s)").test(e.className)}function te(e,t){return e.classList?e.classList.add(t):ee(e,t)||(e.className=(e.className+" "+t).trim()),e}function ie(e,t){return e?(e.classList?e.classList.remove(t):(z(t),e.className=e.className.split(/\s+/).filter(function(e){return e!==t}).join(" ")),e):(h.warn("removeClass was called with an element that doesn't exist"),null)}function ne(e,t,i){var n=ee(e,t);if((i="boolean"!=typeof(i="function"==typeof i?i(e,t):i)?!n:i)!==n)return(i?te:ie)(e,t),e}function re(i,n){Object.getOwnPropertyNames(n).forEach(function(e){var t=n[e];null===t||"undefined"==typeof t||!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})}function ae(e){var t={},i=",autoplay,controls,playsinline,loop,muted,default,defaultMuted,";if(e&&e.attributes&&0<e.attributes.length)for(var n=e.attributes,r=n.length-1;0<=r;r--){var a=n[r].name,s=n[r].value;"boolean"!=typeof e[a]&&-1===i.indexOf(","+a+",")||(s=null!==s),t[a]=s}return t}function se(e,t){return e.getAttribute(t)}function oe(e,t,i){e.setAttribute(t,i)}function ue(e,t){e.removeAttribute(t)}function le(){document.body.focus(),document.onselectstart=function(){return!1}}function ce(){document.onselectstart=function(){return!0}}function de(e){if(e&&e.getBoundingClientRect&&e.parentNode){var t=e.getBoundingClientRect(),i={};return["bottom","height","left","right","top","width"].forEach(function(e){void 0!==t[e]&&(i[e]=t[e])}),i.height||(i.height=parseFloat(w(e,"height"))),i.width||(i.width=parseFloat(w(e,"width"))),i}}function he(e){if(!e||e&&!e.offsetParent)return{left:0,top:0,width:0,height:0};for(var t=e.offsetWidth,i=e.offsetHeight,n=0,r=0;e.offsetParent&&e!==document[l.fullscreenElement];)n+=e.offsetLeft,r+=e.offsetTop,e=e.offsetParent;return{left:n,top:r,width:t,height:i}}function pe(e,t){var i={x:0,y:0};if(q)for(var n=e;n&&"html"!==n.nodeName.toLowerCase();){var r,a=w(n,"transform");
4707/^matrix/.test(a)?(r=a.slice(7,-1).split(/,\s/).map(Number),i.x+=r[4],i.y+=r[5]):/^matrix3d/.test(a)&&(a=a.slice(9,-1).split(/,\s/).map(Number),i.x+=a[12],i.y+=a[13]),n=n.parentNode}var s={},o=he(t.target),u=he(e),l=u.width,c=u.height,e=t.offsetY-(u.top-o.top),o=t.offsetX-(u.left-o.left);return t.changedTouches&&(o=t.changedTouches[0].pageX-u.left,e=t.changedTouches[0].pageY+u.top,q&&(o-=i.x,e-=i.y)),s.y=1-Math.max(0,Math.min(1,e/c)),s.x=Math.max(0,Math.min(1,o/l)),s}function fe(e){return T(e)&&3===e.nodeType}function me(e){for(;e.firstChild;)e.removeChild(e.firstChild);return e}function ge(e){return"function"==typeof e&&(e=e()),(Array.isArray(e)?e:[e]).map(function(e){return K(e="function"==typeof e?e():e)||fe(e)?e:"string"==typeof e&&/\S/.test(e)?document.createTextNode(e):void 0}).filter(function(e){return e})}function ye(t,e){return ge(e).forEach(function(e){return t.appendChild(e)}),t}function ve(e,t){return ye(me(e),t)}function _e(e){return void 0===e.button&&void 0===e.buttons||(0===e.button&&void 0===e.buttons||("mouseup"===e.type&&0===e.button&&0===e.buttons||0===e.button&&1===e.buttons))}var be,Te=Q("querySelector"),Se=Q("querySelectorAll"),we=Object.freeze({__proto__:null,isReal:X,isEl:K,isInFrame:Y,createEl:$,textContent:J,prependTo:Z,hasClass:ee,addClass:te,removeClass:ie,toggleClass:ne,setAttributes:re,getAttributes:ae,getAttribute:se,setAttribute:oe,removeAttribute:ue,blockTextSelection:le,unblockTextSelection:ce,getBoundingClientRect:de,findPosition:he,getPointerPosition:pe,isTextNode:fe,emptyEl:me,normalizeContent:ge,appendContent:ye,insertContent:ve,isSingleLeftClick:_e,$:Te,$$:Se}),Ee=!1,ke=function(){if(!1!==be.options.autoSetup){var e=Array.prototype.slice.call(document.getElementsByTagName("video")),t=Array.prototype.slice.call(document.getElementsByTagName("audio")),i=Array.prototype.slice.call(document.getElementsByTagName("video-js")),n=e.concat(t,i);if(n&&0<n.length)for(var r=0,a=n.length;r<a;r++){var s=n[r];if(!s||!s.getAttribute){Ce(1);break}void 0===s.player&&null!==s.getAttribute("data-setup")&&be(s)}else Ee||Ce(1)}};function Ce(e,t){X()&&(t&&(be=t),window.setTimeout(ke,e))}function Ie(){Ee=!0,window.removeEventListener("load",Ie)}X()&&("complete"===document.readyState?Ie():window.addEventListener("load",Ie));function xe(e){var t=document.createElement("style");return t.className=e,t}function Ae(e,t){e.styleSheet?e.styleSheet.cssText=t:e.textContent=t}var Pe=3;window.WeakMap||(ui=function(){function e(){this.vdata="vdata"+Math.floor(window.performance&&window.performance.now()||Date.now()),this.data={}}var t=e.prototype;return t.set=function(e,t){var i=e[this.vdata]||Pe++;return e[this.vdata]||(e[this.vdata]=i),this.data[i]=t,this},t.get=function(e){var t=e[this.vdata];if(t)return this.data[t];h("We have no data for this element",e)},t.has=function(e){return e[this.vdata]in this.data},t.delete=function(e){var t=e[this.vdata];t&&(delete this.data[t],delete e[this.vdata])},e}());var Le,De=new(window.WeakMap?WeakMap:ui);function Oe(e,t){var i;De.has(e)&&(0===(i=De.get(e)).handlers[t].length&&(delete i.handlers[t],e.removeEventListener?e.removeEventListener(t,i.dispatcher,!1):e.detachEvent&&e.detachEvent("on"+t,i.dispatcher)),Object.getOwnPropertyNames(i.handlers).length<=0&&(delete i.handlers,delete i.dispatcher,delete i.disabled),0===Object.getOwnPropertyNames(i).length&&De.delete(e))}function Re(t,i,e,n){e.forEach(function(e){t(i,e,n)})}function Me(e){if(e.fixed_)return e;function t(){return!0}function i(){return!1}if(!e||!e.isPropagationStopped||!e.isImmediatePropagationStopped){var n,r,a,s=e||window.event;for(n in e={},s)"layerX"!==n&&"layerY"!==n&&"keyLocation"!==n&&"webkitMovementX"!==n&&"webkitMovementY"!==n&&("returnValue"===n&&s.preventDefault||(e[n]=s[n]));e.target||(e.target=e.srcElement||document),e.relatedTarget||(e.relatedTarget=e.fromElement===e.target?e.toElement:e.fromElement),e.preventDefault=function(){s.preventDefault&&s.preventDefault(),e.returnValue=!1,s.returnValue=!1,e.defaultPrevented=!0},e.defaultPrevented=!1,e.stopPropagation=function(){s.stopPropagation&&s.stopPropagation(),e.cancelBubble=!0,s.cancelBubble=!0,e.isPropagationStopped=t},e.isPropagationStopped=i,e.stopImmediatePropagation=function(){s.stopImmediatePropagation&&s.stopImmediatePropagation(),e.isImmediatePropagationStopped=t,e.stopPropagation()},e.isImmediatePropagationStopped=i,null!==e.clientX&&void 0!==e.clientX&&(r=d
4707ocument.documentElement,a=document.body,e.pageX=e.clientX+(r&&r.scrollLeft||a&&a.scrollLeft||0)-(r&&r.clientLeft||a&&a.clientLeft||0),e.pageY=e.clientY+(r&&r.scrollTop||a&&a.scrollTop||0)-(r&&r.clientTop||a&&a.clientTop||0)),e.which=e.charCode||e.keyCode,null!==e.button&&void 0!==e.button&&(e.button=1&e.button?0:4&e.button?1:2&e.button?2:0)}return e.fixed_=!0,e}var Ne=function(){if("boolean"!=typeof Le){Le=!1;try{var e=Object.defineProperty({},"passive",{get:function(){Le=!0}});window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(e){}}return Le},Ue=["touchstart","touchmove"];function Be(s,e,t){if(Array.isArray(e))return Re(Be,s,e,t);De.has(s)||De.set(s,{});var o=De.get(s);o.handlers||(o.handlers={}),o.handlers[e]||(o.handlers[e]=[]),t.guid||(t.guid=Pe++),o.handlers[e].push(t),o.dispatcher||(o.disabled=!1,o.dispatcher=function(e,t){if(!o.disabled){e=Me(e);var i=o.handlers[e.type];if(i)for(var n=i.slice(0),r=0,a=n.length;r<a&&!e.isImmediatePropagationStopped();r++)try{n[r].call(s,e,t)}catch(e){h.error(e)}}}),1===o.handlers[e].length&&(s.addEventListener?(t=!1,Ne()&&-1<Ue.indexOf(e)&&(t={passive:!0}),s.addEventListener(e,o.dispatcher,t)):s.attachEvent&&s.attachEvent("on"+e,o.dispatcher))}function Fe(e,t,i){if(De.has(e)){var n=De.get(e);if(n.handlers){if(Array.isArray(t))return Re(Fe,e,t,i);var r=function(e,t){n.handlers[t]=[],Oe(e,t)};if(void 0!==t){var a=n.handlers[t];if(a)if(i){if(i.guid)for(var s=0;s<a.length;s++)a[s].guid===i.guid&&a.splice(s--,1);Oe(e,t)}else r(e,t)}else for(var o in n.handlers)Object.prototype.hasOwnProperty.call(n.handlers||{},o)&&r(e,o)}}}function je(e,t,i){var n=De.has(e)?De.get(e):{},r=e.parentNode||e.ownerDocument;return"string"==typeof t?t={type:t,target:e}:t.target||(t.target=e),t=Me(t),n.dispatcher&&n.dispatcher.call(e,t,i),r&&!t.isPropagationStopped()&&!0===t.bubbles?je.call(null,r,t,i):!r&&!t.defaultPrevented&&t.target&&t.target[t.type]&&(De.has(t.target)||De.set(t.target,{}),r=De.get(t.target),t.target[t.type]&&(r.disabled=!0,"function"==typeof t.target[t.type]&&t.target[t.type](),r.disabled=!1)),!t.defaultPrevented}function He(e,t,i){if(Array.isArray(t))return Re(He,e,t,i);function n(){Fe(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||Pe++,Be(e,t,n)}function qe(e,t,i){function n(){Fe(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||Pe++,Be(e,t,n)}function Ve(e,t,i){return t.guid||(t.guid=Pe++),(e=t.bind(e)).guid=i?i+"_"+t.guid:t.guid,e}function We(t,i){var n=window.performance.now();return function(){var e=window.performance.now();i<=e-n&&(t.apply(void 0,arguments),n=e)}}function Ge(n,r,a,s){var o;function e(){var e=this,t=arguments,i=function(){i=o=null,a||n.apply(e,t)};!o&&a&&n.apply(e,t),s.clearTimeout(o),o=s.setTimeout(i,r)}return void 0===s&&(s=window),e.cancel=function(){s.clearTimeout(o),o=null},e}function ze(){}var Xe,Ke=Object.freeze({__proto__:null,fixEvent:Me,on:Be,off:Fe,trigger:je,one:He,any:qe});ze.prototype.allowedEvents_={},ze.prototype.addEventListener=ze.prototype.on=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},Be(this,e,t),this.addEventListener=i},ze.prototype.removeEventListener=ze.prototype.off=function(e,t){Fe(this,e,t)},ze.prototype.one=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},He(this,e,t),this.addEventListener=i},ze.prototype.any=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},qe(this,e,t),this.addEventListener=i},ze.prototype.dispatchEvent=ze.prototype.trigger=function(e){var t=e.type||e;e=Me(e="string"==typeof e?{type:t}:e),this.allowedEvents_[t]&&this["on"+t]&&this["on"+t](e),je(this,e)},ze.prototype.queueTrigger=function(e){var t=this;Xe=Xe||new Map;var i=e.type||e,n=Xe.get(this);n||(n=new Map,Xe.set(this,n));var r=n.get(i);n.delete(i),window.clearTimeout(r);r=window.setTimeout(function(){0===n.size&&(n=null,Xe.delete(t)),t.trigger(e)},0);n.set(i,r)};function Ye(e){return"function"==typeof e.name?e.name():"string"==typeof e.name?e.name:e.name_||(e.constructor&&e.constructor.name?e.constructor.name:typeof e)}function Qe(e){return"string"==typeof e&&/\S/.test(e)||Array.isArray(e)&&!!e.length}function $e(e,t,i){if(!e||!e.nodeName&&!it(e))throw new Error("Invalid target for "+Ye(t)+"#"+i+"; must be a DOM node or evented object.")}function Je(e,t,i){if(!Qe(e))throw new Error("Invalid event type for "+Ye(t)+"#"+i+"; must be a non-empty string or array.")}function Ze(e,t,i){if("function"!=typeof e)throw new Error("Invalid listener for "+Ye(t)+"#"+i+"; must be a function.")}function et(e,t,i){var n,r,a=t.length<3||t[0]===e||t[0]===e.eventBusEl_,t=a?(n=e.eventBusEl_,3<=t.length&&t.shift(),r=t[0],t[1]):(n=t[0],r=t[1],t[2]);return $e(n,e,i),Je(r,e,i),Ze(t,e,i),{isTargetingSelf:a,target:n,type:r,listener:t=Ve(e,t)}}function tt(e,t,i,n){$e(e,e,t),e.nodeName?Ke[t](e,i,n):e[t](i,n)}var it=function(t){return t instanceof ze||!!t.eventBusEl_&&["on","one","off","trigger"].every(function(e){return"function"==typeof t[e]}
4707)},nt={on:function(){for(var e=this,t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];var r,a=et(this,i,"on"),s=a.isTargetingSelf,o=a.target,u=a.type,l=a.listener;tt(o,"on",u,l),s||((r=function(){return e.off(o,u,l)}).guid=l.guid,(s=function(){return e.off("dispose",r)}).guid=l.guid,tt(this,"on","dispose",r),tt(o,"on","dispose",s))},one:function(){for(var r=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=et(this,t,"one"),a=n.isTargetingSelf,s=n.target,o=n.type,u=n.listener;a?tt(s,"one",o,u):((a=function e(){r.off(s,o,e);for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];u.apply(null,i)}).guid=u.guid,tt(s,"one",o,a))},any:function(){for(var r=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=et(this,t,"any"),a=n.isTargetingSelf,s=n.target,o=n.type,u=n.listener;a?tt(s,"any",o,u):((a=function e(){r.off(s,o,e);for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];u.apply(null,i)}).guid=u.guid,tt(s,"any",o,a))},off:function(e,t,i){!e||Qe(e)?Fe(this.eventBusEl_,e,t):(t=t,$e(e=e,this,"off"),Je(t,this,"off"),Ze(i,this,"off"),i=Ve(this,i),this.off("dispose",i),e.nodeName?(Fe(e,t,i),Fe(e,"dispose",i)):it(e)&&(e.off(t,i),e.off("dispose",i)))},trigger:function(e,t){$e(this.eventBusEl_,this,"trigger");var i=e&&"string"!=typeof e?e.type:e;if(!Qe(i)){i="Invalid event type for "+Ye(this)+"#trigger; must be a non-empty string or object with a type key that has a non-empty value.";if(!e)throw new Error(i);(this.log||h).error(i)}return je(this.eventBusEl_,e,t)}};function rt(e,t){t=(t=void 0===t?{}:t).eventBusKey;if(t){if(!e[t].nodeName)throw new Error('The eventBusKey "'+t+'" does not refer to an element.');e.eventBusEl_=e[t]}else e.eventBusEl_=$("span",{className:"vjs-event-bus"});return b(e,nt),e.eventedCallbacks&&e.eventedCallbacks.forEach(function(e){e()}),e.on("dispose",function(){e.off(),[e,e.el_,e.eventBusEl_].forEach(function(e){e&&De.has(e)&&De.delete(e)}),window.setTimeout(function(){e.eventBusEl_=null},0)}),e}var at={state:{},setState:function(e){var i,n=this;return _(e="function"==typeof e?e():e,function(e,t){n.state[t]!==e&&((i=i||{})[t]={from:n.state[t],to:e}),n.state[t]=e}),i&&it(this)&&this.trigger({changes:i,type:"statechanged"}),i}};function st(e,t){return b(e,at),e.state=b({},e.state,t),"function"==typeof e.handleStateChanged&&it(e)&&e.on("statechanged",e.handleStateChanged),e}function ot(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toLowerCase()})}function ut(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toUpperCase()})}function lt(){for(var i={},e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.forEach(function(e){e&&_(e,function(e,t){S(e)?(S(i[t])||(i[t]={}),i[t]=lt(i[t],e)):i[t]=e})}),i}var ct=window.Map||function(){function e(){this.map_={}}var t=e.prototype;return t.has=function(e){return e in this.map_},t.delete=function(e){var t=this.has(e);return delete this.map_[e],t},t.set=function(e,t){return this.map_[e]=t,this},t.forEach=function(e,t){for(var i in this.map_)e.call(t,this.map_[i],i,this)},e}(),dt=window.Set||function(){function e(){this.set_={}}var t=e.prototype;return t.has=function(e){return e in this.set_},t.delete=function(e){var t=this.has(e);return delete this.set_[e],t},t.add=function(e){return this.set_[e]=1,this},t.forEach=function(e,t){for(var i in this.set_)e.call(t,i,i,this)},e}(),ht=m(function(e,t){function i(e){if(!e||"object"!=typeof e||(t=e.which||e.keyCode||e.charCode)&&(e=t),"number"==typeof e)return o[e];var t=String(e),e=n[t.toLowerCase()];return e||((e=r[t.toLowerCase()])?e:1===t.length?t.charCodeAt(0):void 0)}i.isEventKey=function(e,t){if(e&&"object"==typeof e){var i=e.which||e.keyCode||e.charCode;if(null==i)return!1;if("string"==typeof t){e=n[t.toLowerCase()];if(e)return e===i;if(e=r[t.toLowerCase()])return e===i}else if("number"==typeof t)return t===i;return!1}};for(var n=(t=e.exports=i).code=t.codes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,esc:27,space:32,"page up":33,"page down":34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46,command:91,"left command":91,"right command":93,"numpad *":106,"numpad +":107,"numpad -":109,"numpad .":110,"numpad /":111,"num lock":144,"scroll lock":145,"my computer":182,"my calculator":183,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},r=t.aliases={windows:91,"â§":16,"â¥":18,"â":17,"â":91,ctl:17,control:17,option:18,pause:19,break:19,caps:20,return:13,escape:27,spc:32,spacebar:32,pgup:33,pgdn:34,ins:45,del:46,cmd:91},a=97;a<123;a++)n[String.fromCharCode(a)]=a-32;for(var a=48;a<58;a++)n[a-48]=a;for(a=1;a<13;a++)n["f"+a]=a+111;for(a=0;a<10;a++)n["numpad "+a]=a+96;var s,o=t.names=t.title={};for(a in n)o[n[a]]=a;for(s in r)n[s]=r[s]});ht.code,ht.codes,ht.aliases,ht.names,ht.title;var pt=function(){function s(e,t,i){!e&&this.play?this.player_=e=this:this.player_=e,this.isDisposed_=!1,this.parentComponent_=null,this.options_=lt({},this.options_),t=this.options_=lt(this.options_,t),this.id_=t.id||t.el&&t.el.id,this.id_||(e=e&&e.id&&e.id()||"no_player",this.id_=e+"_component_"+Pe++),this.name_=t.name||null,t.el?this.el_=t.el:!1!==t.createEl&&(this.el_=this.createEl()),!1!==t.evented&&(rt(this,{eventBusKey:this.el_?"el_":null}),this.handleLanguagechange=this.handleLanguagechange.bind(this),this.on(this.player_,"languagechange",this.handleLanguagechange)),st(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},this.childNameIndex_={},this.setTimeoutIds_=new dt,this.setIntervalIds_=new dt,this.rafIds_=new dt,this.namedRafs_=new ct,(this.clearingTimersOnDispose_=!1)!==t.initChildren&&this.initChildren(),this.ready(i),!1!==t.reportTouchActivity&&this.enableTouchActivity()}var e=s.prototype;return e.dispose=function(){if(!this.isDisposed_){if(this.readyQueue_&&(this.readyQueue_.length=0),this.trigger({type:"dispose",bubbles:!1}),this.isDisposed_=!0,this.children_)for(var e=this.children_.length-1;0<=e;e--)this.children_[e].dispose&&this.children_[e].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),this.el_=null),this.player_=null}},e.isDisposed=function(){return Boolean(this.isDisposed_)},e.player=function(){return this.player_},e.options=function(e){return e&&(this.options_=lt(this.options_,e)),this.options_},e.el=function(){return this.el_},e.createEl=function(e,t,i){return $(e,t,i)},e.localize=function(e,i,t){void 0===t&&(t=e);var n=this.player_.language&&this.player_.language(),r=this.player_.languages&&this.player_.languages(),a=r&&r[n],n=n&&n.split("-")[0],n=r&&r[n],t=t;return a&&a[e]?t=a[e]:n&&n[e]&&(t=n[e]),t=i?t.replace(/\{(\d+)\}/g,function(e,t){t=i[t-1];return"undefined"==typeof t?e:t}):t},e.handleLanguagechange=function(){},e.contentEl=function(){return this.contentEl_||this.el_},e.id=function(){return this.id_},e.name=function(){return this.name_},e.children=function(){return this.children_},e.getChildById=function(e){return this.childIndex_[e]},e.getChild=function(e){if(e)return this.childNameIndex_[e]},e.getDescendant=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];for(var t=t.reduce(function(e,t){return e.concat(t)},[]),n=this,r=0;r<t.length;r++)if(!(n=n.getChild(t[r]))||!n.getChild)return;return n},e.addChild=function(e,t,i){if(void 0===t&&(t={}),void 0===i&&(i=this.children_.length),"string"==typeof e){var n=ut(e),r=t.componentClass||n;t.name=n;var a=s.getComponent(r);if(!a)throw new Error("Component "+r+" does not exist");if("function"!=typeof a)return null;a=new a(this.player_||this,t)}else a=e;return a.parentComponent_&&a.parentComponent_.removeChild(a),this.children_.splice(i,0,a),a.parentComponent_=this,"function"==typeof a.id&&(this.childIndex_[a.id()]=a),(n=n||a.name&&ut(a.name()))&&(this.childNameIndex_[n]=a,this.childNameIndex_[ot(n)]=a),"function"==typeof a.el&&a.el()&&(n=null,this.children_[i+1]&&(this.children_[i+1].el_?n=this.children_[i+1].el_:K(this.children_[i+1])&&(n=this.children_[i+1])),this.contentEl().insertBefore(a.el(),n)),a},e.removeChild=function(e){if((e="string"==typeof e?this.getChild(e):e)&&this.children_){for(var t,i=!1,n=this.children_.length-1;0<=n;n--)if(this.children_[n]===e){i=!0,this.children_.splice(n,1);break}i&&(e.parentComponent_=null,this.childIndex_[e.id()]=null,this.childNameIndex_[ut(e.name())]=null,this.childNameIndex_[ot(e.name())]=null,(t=e.el())&&t.parentNode===this.contentEl()&&this.contentEl().removeChild(e.el()))}},e.initChildren=function(){var i,t,e,n=this,r=this.options_.children;r&&(i=this.options_,t=s.getComponent("Tech"),(e=Array.isArray(r)?r:Object.keys(r)).concat(Object.keys(this.options_).filter(function(t){return!e.s
4707ome(function(e){return"string"==typeof e?t===e:t===e.name})})).map(function(e){var t,e="string"==typeof e?r[t=e]||n.options_[t]||{}:(t=e.name,e);return{name:t,opts:e}}).filter(function(e){e=s.getComponent(e.opts.componentClass||ut(e.name));return e&&!t.isTech(e)}).forEach(function(e){var t=e.name,e=e.opts;!1!==(e=void 0!==i[t]?i[t]:e)&&((e=!0===e?{}:e).playerOptions=n.options_.playerOptions,(e=n.addChild(t,e))&&(n[t]=e))}))},e.buildCSSClass=function(){return""},e.ready=function(e,t){if(void 0===t&&(t=!1),e)return this.isReady_?void(t?e.call(this):this.setTimeout(e,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(e))},e.triggerReady=function(){this.isReady_=!0,this.setTimeout(function(){var e=this.readyQueue_;this.readyQueue_=[],e&&0<e.length&&e.forEach(function(e){e.call(this)},this),this.trigger("ready")},1)},e.$=function(e,t){return Te(e,t||this.contentEl())},e.$$=function(e,t){return Se(e,t||this.contentEl())},e.hasClass=function(e){return ee(this.el_,e)},e.addClass=function(e){te(this.el_,e)},e.removeClass=function(e){ie(this.el_,e)},e.toggleClass=function(e,t){ne(this.el_,e,t)},e.show=function(){this.removeClass("vjs-hidden")},e.hide=function(){this.addClass("vjs-hidden")},e.lockShowing=function(){this.addClass("vjs-lock-showing")},e.unlockShowing=function(){this.removeClass("vjs-lock-showing")},e.getAttribute=function(e){return se(this.el_,e)},e.setAttribute=function(e,t){oe(this.el_,e,t)},e.removeAttribute=function(e){ue(this.el_,e)},e.width=function(e,t){return this.dimension("width",e,t)},e.height=function(e,t){return this.dimension("height",e,t)},e.dimensions=function(e,t){this.width(e,!0),this.height(t)},e.dimension=function(e,t,i){if(void 0!==t)return-1!==(""+(t=null===t||t!=t?0:t)).indexOf("%")||-1!==(""+t).indexOf("px")?this.el_.style[e]=t:this.el_.style[e]="auto"===t?"":t+"px",void(i||this.trigger("componentresize"));if(!this.el_)return 0;t=this.el_.style[e],i=t.indexOf("px");return-1!==i?parseInt(t.slice(0,i),10):parseInt(this.el_["offset"+ut(e)],10)},e.currentDimension=function(e){var t=0;if("width"!==e&&"height"!==e)throw new Error("currentDimension only accepts width or height value");return t=w(this.el_,e),0!==(t=parseFloat(t))&&!isNaN(t)||(e="offset"+ut(e),t=this.el_[e]),t},e.currentDimensions=function(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}},e.currentWidth=function(){return this.currentDimension("width")},e.currentHeight=function(){return this.currentDimension("height")},e.focus=function(){this.el_.focus()},e.blur=function(){this.el_.blur()},e.handleKeyDown=function(e){this.player_&&(ht.isEventKey(e,"Tab")||e.stopPropagation(),this.player_.handleKeyDown(e))},e.handleKeyPress=function(e){this.handleKeyDown(e)},e.emitTapEvents=function(){var i,t=0,n=null;this.on("touchstart",function(e){1===e.touches.length&&(n={pageX:e.touches[0].pageX,pageY:e.touches[0].pageY},t=window.performance.now(),i=!0)}),this.on("touchmove",function(e){var t;1<e.touches.length?i=!1:n&&(t=e.touches[0].pageX-n.pageX,e=e.touches[0].pageY-n.pageY,10<Math.sqrt(t*t+e*e)&&(i=!1))});function e(){i=!1}this.on("touchleave",e),this.on("touchcancel",e),this.on("touchend",function(e){!(n=null)===i&&window.performance.now()-t<200&&(e.preventDefault(),this.trigger("tap"))})},e.enableTouchActivity=function(){var t,i,e;this.player()&&this.player().reportUserActivity&&(t=Ve(this.player(),this.player().reportUserActivity),this.on("touchstart",function(){t(),this.clearInterval(i),i=this.setInterval(t,250)}),e=function(e){t(),this.clearInterval(i)},this.on("touchmove",t),this.on("touchend",e),this.on("touchcancel",e))},e.setTimeout=function(e,t){var i,n=this;return e=Ve(this,e),this.clearTimersOnDispose_(),i=window.setTimeout(function(){n.setTimeoutIds_.has(i)&&n.setTimeoutIds_.delete(i),e()},t),this.setTimeoutIds_.add(i),i},e.clearTimeout=function(e){return this.setTimeoutIds_.has(e)&&(this.setTimeoutIds_.delete(e),window.clearTimeout(e)),e},e.setInterval=function(e,t){e=Ve(this,e),this.clearTimersOnDispose_();t=window.setInterval(e,t);return this.setIntervalIds_.add(t),t},e.clearInterval=function(e){return this.setIntervalIds_.has(e)&&(this.setIntervalIds_.delete(e),window.clearInterval(e)),e},e.requestAnimationFrame=function(e){var t,i=this;return this.supportsRaf_?(this.clearTimersOnDispose_(),e=Ve(this,e),t=window.requestAnimationFrame(function(){i.rafIds_.has(t)&&i.rafIds_.delete(t),e()}),this.rafIds_.add(t),t):this.setTimeout(e,1e3/60)},e.requestNamedAnimationFrame=function(e,t){var i=this;if(!this.namedRafs_.has(e)){this.clearTimersOnDispose_(),t=Ve(this,t);var n=this.requestAnimationFrame(function(){t(),i.namedRafs_.has(e)&&i.namedRafs_.delete(e)});return this.namedRafs_.set(e,n),e}},e.cancelNamedAnimationFrame=function(e){this.namedRafs_.has(e)&&(this.cancelAnimationFrame(this.namedRafs_.get(e)),this.namedRafs_.delete(e))},e.cancelAnimationFrame=function(e){return this.supportsRaf_?(this.rafIds_.has(e)&&(this.rafIds_.delete(e),window.cancelAnimationFrame(e)),e):this.clearTimeout(e)},e.clearTimersOnDispose_=function(){var n=this;this.clearingTimersOnDispose_||(this.clearingTimersOnDispose_=!0,this.one("dispose",function(){[["namedRafs_","cancelNamedAnimationFrame"],["rafIds_","cancelAnimationFrame"],["setTimeoutIds_","clearTimeout"],["setIntervalIds_","clearInterval"]].forEac
vendor: 9,904 bytes, line 4707
4707h(function(e){var t=e[0],i=e[1];n[t].forEach(function(e,t){return n[i](t)})}),n.clearingTimersOnDispose_=!1}))},s.registerComponent=function(e,t){if("string"!=typeof e||!e)throw new Error('Illegal component name, "'+e+'"; must be a non-empty string.');var i=s.getComponent("Tech"),n=i&&i.isTech(t),i=s===t||s.prototype.isPrototypeOf(t.prototype);if(n||!i){var r=n?"techs must be registered using Tech.registerTech()":"must be a Component subclass";throw new Error('Illegal component, "'+e+'"; '+r+".")}e=ut(e),s.components_||(s.components_={});r=s.getComponent("Player");if("Player"===e&&r&&r.players){var a=r.players,r=Object.keys(a);if(a&&0<r.length&&r.map(function(e){return a[e]}).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return s.components_[e]=t,s.components_[ot(e)]=t},s.getComponent=function(e){if(e&&s.components_)return s.components_[e]},s}();pt.prototype.supportsRaf_="function"==typeof window.requestAnimationFrame&&"function"==typeof window.cancelAnimationFrame,pt.registerComponent("Component",pt);var ft=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e};var mt=function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t};function gt(e,t,i,n){return function(e,t,i){if("number"!=typeof t||t<0||i<t)throw new Error("Failed to execute '"+e+"' on 'TimeRanges': The index provided ("+t+") is non-numeric or out of bounds (0-"+i+").")}(e,n,i.length-1),i[n][t]}function yt(e){var t=void 0===e||0===e.length?{length:0,start:function(){throw new Error("This TimeRanges object is empty")},end:function(){throw new Error("This TimeRanges object is empty")}}:{length:e.length,start:gt.bind(null,"start",0,e),end:gt.bind(null,"end",1,e)};return window.Symbol&&window.Symbol.iterator&&(t[window.Symbol.iterator]=function(){return(e||[]).values()}),t}function vt(e,t){return Array.isArray(e)?yt(e):void 0===e||void 0===t?yt():yt([[e,t]])}function _t(e,t){var i,n,r=0;if(!t)return 0;e&&e.length||(e=vt(0,0));for(var a=0;a<e.length;a++)i=e.start(a),r+=(n=t<(n=e.end(a))?t:n)-i;return r/t}function bt(e){if(e instanceof bt)return e;"number"==typeof e?this.code=e:"string"==typeof e?this.message=e:T(e)&&("number"==typeof e.code&&(this.code=e.code),b(this,e)),this.message||(this.message=bt.defaultMessages[this.code]||"")}bt.prototype.code=0,bt.prototype.message="",bt.prototype.status=null,bt.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],bt.defaultMessages={1:"You aborted the media playback",2:"A network error caused the media download to fail part-way.",3:"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",4:"The media could not be loaded, either because the server or network failed or because the format is not supported.",5:"The media is encrypted and we do not have the keys to decrypt it."};for(var Tt=0;Tt<bt.errorTypes.length;Tt++)bt[bt.errorTypes[Tt]]=Tt,bt.prototype[bt.errorTypes[Tt]]=Tt;var St=function(e,t){var i,n=null;try{i=JSON.parse(e,t)}catch(e){n=e}return[n,i]};function wt(e){return null!=e&&"function"==typeof e.then}function Et(e){wt(e)&&e.then(null,function(e){})}function kt(n){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(function(e,t,i){return n[t]&&(e[t]=n[t]),e},{cues:n.cues&&Array.prototype.map.call(n.cues,function(e){return{startTime:e.startTime,endTime:e.endTime,text:e.text,id:e.id}})})}var Ct=function(e){var t=e.$$("track"),i=Array.prototype.map.call(t,function(e){return e.track});return Array.prototype.map.call(t,function(e){var t=kt(e.track);return e.src&&(t.src=e.src),t}).concat(Array.prototype.filter.call(e.textTracks(),function(e){return-1===i.indexOf(e)}).map(kt))},It=function(e,i){return e.forEach(function(e){var t=i.addRemoteTextTrack(e).track;!e.src&&e.cues&&e.cues.forEach(function(e){return t.addCue(e)})}),i.textTracks()},xt="vjs-modal-dialog",At=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.close_=function(e){return i.close(e)},i.opened_=i.hasBeenOpened_=i.hasBeenFilled_=!1,i.closeable(!i.options_.uncloseable),i.content(i.options_.content),i.contentEl_=$("div",{className:xt+"-content"},{role:"document"}),i.descEl_=$("p",{className:xt+"-description vjs-control-text",id:i.el().getAttribute("aria-describedby")}),J(i.descEl_,i.description()),i.el_.appendChild(i.descEl_),i.el_.appendChild(i.contentEl_),i}mt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":this.id()+"_description","aria-hidden":"true","aria-label":this.label(),role:"dialog"})},t.dispose=function(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return xt+" vjs-hidden "+n.prototype.buildCSSClass.call(this)},t.label=function(){return this.localize(this.options_.label||"Modal Window")},t.description=function(){var e=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(e+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),e},t.open=function(){var e;this.opened_||(e=this.player(),this.trigger("beforemodalopen"),this.opened_=!0,!this.options_.fillAlways&&(this.hasBeenOpened_||this.hasBeenFilled_)||this.fill(),this.wasPlaying_=!e.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&e.pause(),this.on("keydown",this.handleKeyDown_),this.hadControls_=e.controls(),e.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0)},t.opened=function(e){return"boolean"==typeof e&&this[e?"open":"close"](),this.opened_},t.close=function(){var e;this.opened_&&(e=this.player(),this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&e.play(),this.off("keydown",this.handleKeyDown_),this.hadControls_&&e.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose())},t.closeable=function(e){var t,i;return"boolean"==typeof e&&(t=this.closeable_=!!e,i=this.getChild("closeButton"),t&&!i&&(e=this.contentEl_,this.contentEl_=this.el_,i=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=e,this.on(i,"close",this.close_)),!t&&i&&(this.off(i,"close",this.close_),this.removeChild(i),i.dispose())),this.closeable_},t.fill=function(){this.fillWith(this.content())},t.fillWith=function(e){var t=this.contentEl(),i=t.parentNode,n=t.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,i.removeChild(t),this.empty(),ve(t,e),this.trigger("modalfill"),n?i.insertBefore(t,n):i.appendChild(t);t=this.getChild("closeButton");t&&i.appendChild(t.el_)},t.empty=function(){this.trigger("beforemodalempty"),me(this.contentEl()),this.trigger("modalempty")},t.content=function(e){return"undefined"!=typeof e&&(this.content_=e),this.content_},t.conditionalFocus_=function(){var e=document.activeElement,t=this.player_.el_;this.previouslyActiveEl_=null,!t.contains(e)&&t!==e||(this.previouslyActiveEl_=e,this.focus())},t.conditionalBlur_=function(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)},t.handleKeyDown=function(e){if(e.stopPropagation(),ht.isEventKey(e,"Escape")&&this.closeable())return e.preventDefault(),void this.close();if(ht.isEventKey(e,"Tab")){for(var t,i=this.focusableEls_(),n=this.el_.querySelector(":focus"),r=0;r<i.length;r++)if(n===i[r]){t=r;break}document.activeElement===this.el_&&(t=0),e.shiftKey&&0===t?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||t!==i.length-1||(i[0].focus(),e.preventDefault())}},t.focusableEls_=function(){var e=this.el_.querySelectorAll("*");return Array.prototype.filter.call(e,function(e){return(e instanceof window.HTMLAnchorElement||e instanceof window.HTMLAreaElement)&&e.hasAttribute("href")||(e instanceof window.HTMLInputElement||e instanceof window.HTMLSelectElement||e instanceof window.HTMLTextAreaElement||e instanceof window.HTMLButtonElement)&&!e.hasAttribute("disabled")||e instanceof window.HTMLIFrameElement||e instanceof window.HTMLObjectElement||e instanceof window.HTMLEmbedElement||e.hasAttribute("tabindex")&&-1!==e.getAttribute("tabindex")||e.hasAttribute("contenteditable")})},e}(pt);At.prototype.options_={pauseOnOpen:!0,temporary:!0},pt.registerComponent("ModalDialog",At);var Pt,Lt=function(n){function e(e){var t;void 0===e&&(e=[]),(t=n.call(this)||this).tracks_=[],Object.defineProperty(ft(t),"length",{get:function(){return this.tracks_.length}});for(var i=0;i<e.length;i++)t.addTrack(e[i]);return t}mt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this,i=this.tracks_.length;""+i in this||Object.defineProperty(this,i,{get:function(){return this.tracks_[i]}}),-1===this.tracks_.indexOf(e)&&(this.tracks_.push(e),this.trigger({track:e,type:"addtrack",target:this})),e.labelchange_=function(){t.trigger({track:e,type:"labelchange",target:t})},it(e)&&e.addEventListener("labelchange",e.labelchange_)},t.removeTrack=function(e){for(var t,i=0,n=this.length;i<n;i++)if(this[i]===e){(t=this[i]).off&&t.off(),this.tracks_.splice(i,1);break}t&&this.trigger({track:t,type:"removetrack",target:this})},t.getTrackById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},e}(ze);for(Pt in Lt.prototype.allowedEvents_={change:"change",addtrack:"addtrack",removetrack:"removetrack",labelchange:"labelchange"},Lt.prototype.allowedEvents_)Lt.prototype["on"+Pt]=null;function Dt(e,t){for(var i=0;i<e.length;
4707i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].enabled=!1)}function Ot(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].selected=!1)}function Rt(e){var t=["protocol","hostname","port","pathname","search","hash","host"],i=document.createElement("a");i.href=e;for(var n={},r=0;r<t.length;r++)n[t[r]]=i[t[r]];return"http:"===n.protocol&&(n.host=n.host.replace(/:80$/,"")),"https:"===n.protocol&&(n.host=n.host.replace(/:443$/,"")),n.protocol||(n.protocol=window.location.protocol),n.host||(n.host=window.location.host),n}function Mt(e){var t;return e.match(/^https?:\/\//)||((t=document.createElement("a")).href=e,e=t.href),e}function Nt(e){if("string"==typeof e){e=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/.exec(e);if(e)return e.pop().toLowerCase()}return""}function Ut(e,t){return void 0===t&&(t=window.location),(":"===(e=Rt(e)).protocol?t:e).protocol+e.host!==t.protocol+t.host}var Bt=function(n){function e(e){for(var t,i=(e=void 0===e?[]:e).length-1;0<=i;i--)if(e[i].enabled){Dt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,t}mt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.enabled&&Dt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.enabledChange_=function(){t.changing_||(t.changing_=!0,Dt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("enabledchange",e.enabledChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.enabledChange_&&(e.removeEventListener("enabledchange",e.enabledChange_),e.enabledChange_=null)},e}(Lt),Ft=function(n){function e(e){for(var t,i=(e=void 0===e?[]:e).length-1;0<=i;i--)if(e[i].selected){Ot(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,Object.defineProperty(ft(t),"selectedIndex",{get:function(){for(var e=0;e<this.length;e++)if(this[e].selected)return e;return-1},set:function(){}}),t}mt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.selected&&Ot(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.selectedChange_=function(){t.changing_||(t.changing_=!0,Ot(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("selectedchange",e.selectedChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.selectedChange_&&(e.removeEventListener("selectedchange",e.selectedChange_),e.selectedChange_=null)},e}(Lt),k=function(i){function e(){return i.apply(this,arguments)||this}mt(e,i);var t=e.prototype;return t.addTrack=function(e){var t=this;i.prototype.addTrack.call(this,e),this.queueChange_||(this.queueChange_=function(){return t.queueTrigger("change")}),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=function(){return t.trigger("selectedlanguagechange")}),e.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(e.kind)&&e.addEventListener("modechange",this.triggerSelectedlanguagechange_)},t.removeTrack=function(e){i.prototype.removeTrack.call(this,e),e.removeEventListener&&(this.queueChange_&&e.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&e.removeEventListener("modechange",this.triggerSelectedlanguagechange_))},e}(Lt),jt=function(){function e(e){void 0===e&&(e=[]),this.trackElements_=[],Object.defineProperty(this,"length",{get:function(){return this.trackElements_.length}});for(var t=0,i=e.length;t<i;t++)this.addTrackElement_(e[t])}var t=e.prototype;return t.addTrackElement_=function(e){var t=this.trackElements_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.trackElements_[t]}}),-1===this.trackElements_.indexOf(e)&&this.trackElements_.push(e)},t.getTrackElementByTrack_=function(e){for(var t,i=0,n=this.trackElements_.length;i<n;i++)if(e===this.trackElements_[i].track){t=this.trackElements_[i];break}return t},t.removeTrackElement_=function(e){for(var t=0,i=this.trackElements_.length;t<i;t++)if(e===this.trackElements_[t]){this.trackElements_[t].track&&"function"==typeof this.trackElements_[t].track.off&&this.trackElements_[t].track.off(),"function"==typeof this.trackElements_[t].off&&this.trackElements_[t].off(),this.trackElements_.splice(t,1);break}},e}(),Ht=function(){function t(e){t.prototype.setCues_.call(this,e),Object.defineProperty(this,"length",{get:function(){return this.length_}})}var e=t.prototype;return e.setCues_=function(e){var t=this.length||0,i=0,n=e.length;this.cues_=e,this.length_=e.length;function r(e){""+e in this||Object.defineProperty(this,""+e,{get:function(){return this.cues_[e]}})}if(t<n)for(i=t;i<n;i++)r.call(this,i)},e.getCueById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},t}(),qt={alternative:"alternative",captions:"captions",main:"main",sign:"sign",subtitles:"subtitles",commentary:"commentary"},Vt={alternative:"alternative",descriptions:"descriptions",main:"main","main-desc":"main-desc",translation:"translation",commentary:"commentary"},Wt={subtitles:"subtitles",captions:"captions",descriptions:"descriptions",chapters:"chapters",metadata:"metadata"},Gt={disabled:"disabled",hidden:"hidden",showing:"showing"},C=function(a){function e(e){void 0===e&&(e={});var t,i=a.call(this)||this,n={id:e.id||"vjs_track_"+Pe++,kind:e.kind||"",language:e.language||""},r=e.label||"";for(t in n)!function(e){Object.defineProperty(ft(i),e,{get:function(){return n[e]},set:function(){}})}(t);return Object.defineProperty(ft(i),"label",{get:function(){return r},set:function(e){e!==r&&(r=e,this.trigger("labelchange"))}}),i}return mt(e,a),e}(ze),zt=Object.freeze({__proto__:null,parseUrl:Rt,getAbsoluteURL:Mt,getFileExtension:Nt,isCrossOrigin:Ut}),Xt="undefined"!=typeof window?window:"undefined"!=typeof f?f:"undefined"!=typeof self?self:{},Kt=Xt,Yt=function(e){if(!e)return!1;var t=Qt.call(e);return"[object Function]"===t||"function"==typeof e&&"[object RegExp]"!==t||"undefined"!=typeof window&&(e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt)},Qt=Object.prototype.toString;ei.httpHandler=function(n,r){return void 0===r&&(r=!1),function(e,t,i){if(e)n(e);else if(400<=t.statusCode&&t.statusCode<=599){e=i;if(r)if(Kt.TextDecoder){t=function(e){void 0===e&&(e="");return e.toLowerCase().split(";").reduce(function(e,t){var i=t.split("="),t=i[0],i=i[1];return"charset"===t.trim()?i.trim():e},"utf-8")}(t.headers&&t.headers["content-type"]);try{e=new TextDecoder(t).decode(i)}catch(e){}}else e=String.fromCharCode.apply(null,new Uint8Array(i));n({cause:e})}else n(null,i)}}; 4708 /** 4709 * @license 4710 * slighly modified parse-headers 2.0.2 <https://github.com/kesla/parse-headers/> 4711 * Copyright (c) 2014 David Björklund 4712 * Available under the MIT license 4713 * <https://github.com/kesla/parse-headers/blob/master/LICENCE> 4714 */ 4715 var $t=function(e){var n={};return e&&e.trim().split("\n").forEach(function(e){var t=e.indexOf(":"),i=e.slice(0,t).trim().toLowerCase(),t=e.slice(t+1).trim();"undefined"==typeof n[i]?n[i]=t:Array.isArray(n[i])?n[i].push(t):n[i]=[n[i],t]}),n},Jt=ei,I=ei;function Zt(e,t,i){var n=e;
4715return Yt(t)?(i=t,"string"==typeof e&&(n={uri:e})):n=g({},t,{uri:e}),n.callback=i,n}function ei(e,t,i){return ti(t=Zt(e,t,i))}function ti(n){if("undefined"==typeof n.callback)throw new Error("callback argument missing");var r=!1,a=function(e,t,i){r||(r=!0,n.callback(e,t,i))};function s(){var e=void 0,e=l.response||l.responseText||function(e){try{if("document"===e.responseType)return e.responseXML;var t=e.responseXML&&"parsererror"===e.responseXML.documentElement.nodeName;if(""===e.responseType&&!t)return e.responseXML}catch(e){}return null}(l);if(m)try{e=JSON.parse(e)}catch(e){}return e}function t(e){return clearTimeout(u),(e=!(e instanceof Error)?new Error(""+(e||"Unknown XMLHttpRequest Error")):e).statusCode=0,a(e,g)}function e(){if(!o){clearTimeout(u);var e=n.useXDR&&void 0===l.status?200:1223===l.status?204:l.status,t=g,i=null;return 0!==e?(t={body:s(),statusCode:e,method:d,headers:{},url:c,rawRequest:l},l.getAllResponseHeaders&&(t.headers=$t(l.getAllResponseHeaders()))):i=new Error("Internal XMLHttpRequest Error"),a(i,t,t.body)}}var i,o,u,l=n.xhr||null,c=(l=l||new(n.cors||n.useXDR?ei.XDomainRequest:ei.XMLHttpRequest)).url=n.uri||n.url,d=l.method=n.method||"GET",h=n.body||n.data,p=l.headers=n.headers||{},f=!!n.sync,m=!1,g={body:void 0,headers:{},statusCode:0,method:d,url:c,rawRequest:l};if("json"in n&&!1!==n.json&&(m=!0,p.accept||p.Accept||(p.Accept="application/json"),"GET"!==d&&"HEAD"!==d&&(p["content-type"]||p["Content-Type"]||(p["Content-Type"]="application/json"),h=JSON.stringify(!0===n.json?h:n.json))),l.onreadystatechange=function(){4===l.readyState&&setTimeout(e,0)},l.onload=e,l.onerror=t,l.onprogress=function(){},l.onabort=function(){o=!0},l.ontimeout=t,l.open(d,c,!f,n.username,n.password),f||(l.withCredentials=!!n.withCredentials),!f&&0<n.timeout&&(u=setTimeout(function(){var e;o||(o=!0,l.abort("timeout"),(e=new Error("XMLHttpRequest timeout")).code="ETIMEDOUT",t(e))},n.timeout)),l.setRequestHeader)for(i in p)p.hasOwnProperty(i)&&l.setRequestHeader(i,p[i]);else if(n.headers&&!function(e){for(var t in e)if(e.hasOwnProperty(t))return;return 1}(n.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in n&&(l.responseType=n.responseType),"beforeSend"in n&&"function"==typeof n.beforeSend&&n.beforeSend(l),l.send(h||null),l}ei.XMLHttpRequest=Kt.XMLHttpRequest||function(){},ei.XDomainRequest="withCredentials"in new ei.XMLHttpRequest?ei.XMLHttpRequest:Kt.XDomainRequest,function(e,t){for(var i=0;i<e.length;i++)t(e[i])}(["get","put","post","patch","head","delete"],function(n){ei["delete"===n?"del":n]=function(e,t,i){return(t=Zt(e,t,i)).method=n.toUpperCase(),ti(t)}}),Jt.default=I;function ii(e,t){var i=new window.WebVTT.Parser(window,window.vttjs,window.WebVTT.StringDecoder()),n=[];i.oncue=function(e){t.addCue(e)},i.onparsingerror=function(e){n.push(e)},i.onflush=function(){t.trigger({type:"loadeddata",target:t})},i.parse(e),0<n.length&&(window.console&&window.console.groupCollapsed&&window.console.groupCollapsed("Text Track parsing errors for "+t.src),n.forEach(function(e){return h.error(e)}),window.console&&window.console.groupEnd&&window.console.groupEnd()),i.flush()}function ni(e,n){var t={uri:e};(e=Ut(e))&&(t.cors=e),(e="use-credentials"===n.tech_.crossOrigin())&&(t.withCredentials=e),Jt(t,Ve(this,function(e,t,i){return e?h.error(e,t):(n.loaded_=!0,void("function"!=typeof window.WebVTT?n.tech_&&n.tech_.any(["vttjsloaded","vttjserror"],function(e){return"vttjserror"!==e.type?ii(i,n):void h.error("vttjs failed to load, stopping trying to process "+n.src)}):ii(i,n)))}))}var ri=function(u){function e(e){var t;if(!(e=void 0===e?{}:e).tech)throw new Error("A tech was not provided.");var e=lt(e,{kind:Wt[e.kind]||"subtitles",language:e.language||e.srclang||""}),i=Gt[e.mode]||"disabled",n=e.default;"metadata"!==e.kind&&"chapters"!==e.kind||(i="hidden"),(t=u.call(this,e)||this).tech_=e.tech,t.cues_=[],t.activeCues_=[],t.preload_=!1!==t.tech_.preloadTextTracks;var r=new Ht(t.cues_),s=new Ht(t.activeCues_),o=!1,a=Ve(ft(t),function(){this.tech_.isReady_&&!this.tech_.isDisposed()&&(this.activeCues=this.activeCues,o&&(this.trigger("cuechange"),o=!1))});return t.tech_.one("dispose",function(){t.tech_.off("timeupdate",a)}),"disabled"!==i&&t.tech_.on("timeupdate",a),Object.defineProperties(ft(t),{default:{get:function(){return n},set:function(){}},mode:{get:function(){return i},set:function(e){Gt[e]&&i!==e&&(i=e,this.preload_||"disabled"===i||
vendor: 6,806 bytes, line 4715
47150!==this.cues.length||ni(this.src,this),this.tech_.off("timeupdate",a),"disabled"!==i&&this.tech_.on("timeupdate",a),this.trigger("modechange"))}},cues:{get:function(){return this.loaded_?r:null},set:function(){}},activeCues:{get:function(){if(!this.loaded_)return null;if(0===this.cues.length)return s;for(var e=this.tech_.currentTime(),t=[],i=0,n=this.cues.length;i<n;i++){var r=this.cues[i];(r.startTime<=e&&r.endTime>=e||r.startTime===r.endTime&&r.startTime<=e&&r.startTime+.5>=e)&&t.push(r)}if(o=!1,t.length!==this.activeCues_.length)o=!0;else for(var a=0;a<t.length;a++)-1===this.activeCues_.indexOf(t[a])&&(o=!0);return this.activeCues_=t,s.setCues_(this.activeCues_),s},set:function(){}}}),e.src?(t.src=e.src,t.preload_||(t.loaded_=!0),(t.preload_||"subtitles"!==e.kind&&"captions"!==e.kind)&&ni(t.src,ft(t))):t.loaded_=!0,t}mt(e,u);var t=e.prototype;return t.addCue=function(e){var t=e;if(window.vttjs&&!(e instanceof window.vttjs.VTTCue)){for(var i in t=new window.vttjs.VTTCue(e.startTime,e.endTime,e.text),e)i in t||(t[i]=e[i]);t.id=e.id,t.originalCue_=e}for(var n=this.tech_.textTracks(),r=0;r<n.length;r++)n[r]!==this&&n[r].removeCue(t);this.cues_.push(t),this.cues.setCues_(this.cues_)},t.removeCue=function(e){for(var t=this.cues_.length;t--;){var i=this.cues_[t];if(i===e||i.originalCue_&&i.originalCue_===e){this.cues_.splice(t,1),this.cues.setCues_(this.cues_);break}}},e}(C);ri.prototype.allowedEvents_={cuechange:"cuechange"};x=function(n){function e(e){var t=lt(e=void 0===e?{}:e,{kind:Vt[e.kind]||""}),e=n.call(this,t)||this,i=!1;return Object.defineProperty(ft(e),"enabled",{get:function(){return i},set:function(e){"boolean"==typeof e&&e!==i&&(i=e,this.trigger("enabledchange"))}}),t.enabled&&(e.enabled=t.enabled),e.loaded_=!0,e}return mt(e,n),e}(C),U=function(n){function e(e){var t=lt(e=void 0===e?{}:e,{kind:qt[e.kind]||""}),e=n.call(this,t)||this,i=!1;return Object.defineProperty(ft(e),"selected",{get:function(){return i},set:function(e){"boolean"==typeof e&&e!==i&&(i=e,this.trigger("selectedchange"))}}),t.selected&&(e.selected=t.selected),e}return mt(e,n),e}(C),j=function(r){function e(e){var t;void 0===e&&(e={});var i=r.call(this)||this,n=new ri(e);return i.kind=n.kind,i.src=n.src,i.srclang=n.language,i.label=n.label,i.default=n.default,Object.defineProperties(ft(i),{readyState:{get:function(){return t}},track:{get:function(){return n}}}),t=0,n.addEventListener("loadeddata",function(){t=2,i.trigger({type:"load",target:ft(i)})}),i}return mt(e,r),e}(ze);j.prototype.allowedEvents_={load:"load"},j.NONE=0,j.LOADING=1,j.LOADED=2,j.ERROR=3;var ai={audio:{ListClass:Bt,TrackClass:x,capitalName:"Audio"},video:{ListClass:Ft,TrackClass:U,capitalName:"Video"},text:{ListClass:k,TrackClass:ri,capitalName:"Text"}};Object.keys(ai).forEach(function(e){ai[e].getterName=e+"Tracks",ai[e].privateName=e+"Tracks_"});var si={remoteText:{ListClass:k,TrackClass:ri,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:jt,TrackClass:j,capitalName:"RemoteTextTrackEls",getterName:"remoteTextTrackEls",privateName:"remoteTextTrackEls_"}},oi=g({},ai,si);si.names=Object.keys(si),ai.names=Object.keys(ai),oi.names=[].concat(si.names).concat(ai.names);var ui="undefined"!=typeof f?f:"undefined"!=typeof window?window:{},li="undefined"!=typeof document?document:(li=ui["__GLOBAL_DOCUMENT_CACHE@4"])||(ui["__GLOBAL_DOCUMENT_CACHE@4"]={}),Xt=li,ci=Object.create||function(e){if(1!==arguments.length)throw new Error("Object.create shim only accepts one parameter.");return di.prototype=e,new di};function di(){}function hi(e,t){this.name="ParsingError",this.code=e.code,this.message=t||e.message}function pi(e){function t(e,t,i,n){return 3600*(0|e)+60*(0|t)+(0|i)+(0|n)/1e3}e=e.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/);return e?e[3]?t(e[1],e[2],e[3].replace(":",""),e[4]):59<e[1]?t(e[1],e[2],0,e[4]):t(0,e[1],e[2],e[4]):null}function fi(){this.values=ci(null)}function mi(e,t,i,n){var r,a,s=n?e.split(n):[e];for(r in s)"string"==typeof s[r]&&(2===(a=s[r].split(i)).length&&t(a[0],a[1]))}function gi(t,e,s){var i=t;function n(){var e=pi(t);if(null===e)throw new hi(hi.Errors.BadTimeStamp,"Malformed timestamp: "+i);return t=t.replace(/^[^\sa-zA-Z-]+/,""),e}function r(){t=t.replace(/^\s+/,"")}if(r(),e.startTime=n(),r(),"--\x3e"!==t.substr(0,3))throw new hi(hi.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+i);t=t.substr(3),r(),e.endTime=n(),r(),function(e,t){var a=new fi;mi(e,function(e,t){switch(e){case"region":for(var i=s.length-1;0<=i;i--)if(s[i].id===t){a.set(e,s[i].region);break}break;case"vertical":a.alt(e,t,["rl","lr"]);break;case"line":var n=t.split(","),r=n[0];a.integer(e,r),a.percent(e,r)&&a.set("snapToLines",!1),a.alt(e,r,["auto"]),2===n.length&&a.alt("lineAlign",n[1],["start","center","end"]);break;case"position":n=t.split(","),a.percent(e,n[0]),2===n.length&&a.alt("positionAlign",n[1],["start","center","end"]);break;case"size":a.percent(e,t);break;case"align":a.alt(e,t,["start","center","end","left","right"])}},/:/,/\s/),t.region=a.get("region",null),t.vertical=a.get("vertical","");try{t.line=a.get("line","auto")}catch(e){}t.lineAlign=a.get("lineAlign","start"),t.snapToLines=a.get("snapToLines",!0),t.size=a.get("size",100);try{t.align=a.get("align","center")}catch(e){t.align=a.get("align","middle")}try{t.position=a.get("position","auto")}catch(e){t.position=a.get("position",{start:0,left:0,center:50,middle:50,end:100,right:100},t.align)}t.positionAlign=a.get("positionAlign",{start:"start",left:"start",center:"center",middle:"center",end:"end",right:"end"},t.align)}(t,e)}((hi.prototype=ci(Error.prototype)).constructor=hi).Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},fi.prototype={set:function(e,t){this.get(e)||""===t||(this.values[e]=t)},get:function(e,t,i){return i?this.has(e)?this.values[e]:t[i]:this.has(e)?this.values[e]:t},has:function(e){return e in this.values},alt:function(e,t,i){for(var n=0;n<i.length;++n)if(t===i[n]){this.set(e,t);break}},integer:function(e,t){/^-?\d+$/.test(t)&&this.set(e,parseInt(t,10))},percent:function(e,t){return!!(t.match(/^([\d]{1,3})(\.[\d]*)?%$/)&&0<=(t=parseFloat(t))&&t<=100)&&(this.set(e,t),!0)}};var yi=Xt.createElement&&Xt.createElement("textarea"),vi={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},_i={white:"rgba(255,255,255,1)",lime:"rgba(0,255,0,1)",cyan:"rgba(0,255,255,1)",red:"rgba(255,0,0,1)",yellow:"rgba(255,255,0,1)",magenta:"rgba(255,0,255,1)",blue:"rgba(0,0,255,1)",black:"rgba(0,0,0,1)"},bi={v:"title",lang:"lang"},Ti={rt:"ruby"};function Si(e,t){for(var i,n,r,a,s,o,u,l,c,d,h=e.document.createElement("div"),p=h,f=[];null!==(i=function(){if(!t)return null;var e=t.match(/^([^<]*)(<[^>
4715]*>?)?/);return e=e[1]||e[2],t=t.substr(e.length),e}());)"<"!==i[0]?p.appendChild(e.document.createTextNode((s=i,yi.innerHTML=s,s=yi.textContent,yi.textContent="",s))):"/"!==i[1]?(a=pi(i.substr(1,i.length-2)))?(n=e.document.createProcessingInstruction("timestamp",a),p.appendChild(n)):(r=i.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/))&&(l=r[1],c=r[3],d=void 0,d=vi[l],(n=d?(d=e.document.createElement(d),(l=bi[l])&&c&&(d[l]=c.trim()),d):null)&&(o=p,Ti[(u=n).localName]&&Ti[u.localName]!==o.localName||(r[2]&&((a=r[2].split(".")).forEach(function(e){var t=/^bg_/.test(e),e=t?e.slice(3):e;_i.hasOwnProperty(e)&&(e=_i[e],n.style[t?"background-color":"color"]=e)}),n.className=a.join(" ")),f.push(r[1]),p.appendChild(n),p=n))):f.length&&f[f.length-1]===i.substr(2).replace(">","")&&(f.pop(),p=p.parentNode);return h}var wi=[[1470,1470],[1472,1472],[1475,1475],[1478,1478],[1488,1514],[1520,1524],[1544,1544],[1547,1547],[1549,1549],[1563,1563],[1566,1610],[1645,1647],[1649,1749],[1765,1766],[1774,1775],[1786,1805],[1807,1808],[1810,1839],[1869,1957],[1969,1969],[1984,2026],[2036,2037],[2042,2042],[2048,2069],[2074,2074],[2084,2084],[2088,2088],[2096,2110],[2112,2136],[2142,2142],[2208,2208],[2210,2220],[8207,8207],[64285,64285],[64287,64296],[64298,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64449],[64467,64829],[64848,64911],[64914,64967],[65008,65020],[65136,65140],[65142,65276],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67679],[67840,67867],[67872,67897],[67903,67903],[67968,68023],[68030,68031],[68096,68096],[68112,68115],[68117,68119],[68121,68147],[68160,68167],[68176,68184],[68192,68223],[68352,68405],[68416,68437],[68440,68466],[68472,68479],[68608,68680],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[1114109,1114109]];function Ei(e){var t=[],i="";if(!e||!e.childNodes)return"ltr";function a(e,t){for(var i=t.childNodes.length-1;0<=i;i--)e.push(t.childNodes[i])}for(a(t,e);i=function e(t){if(!t||!t.length)return null;var i=t.pop(),n=i.textContent||i.innerText;if(n){var r=n.match(/^.*(\n|\r)/);return r?r[t.length=0]:n}return"ruby"===i.tagName?e(t):i.childNodes?(a(t,i),e(t)):void 0}(t);)for(var n=0;n<i.length;n++)if(function(e){for(var t=0;t<wi.length;t++){var i=wi[t];if(e>=i[0]&&e<=i[1])return 1}}(i.charCodeAt(n)))return"rtl";return"ltr"}function ki(){}function Ci(e,t,i){ki.call(this),this.cue=t,this.cueDiv=Si(e,t.text);var n={color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 0.8)",position:"relative",left:0,right:0,top:0,bottom:0,display:"inline",writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext"};this.applyStyles(n,this.cueDiv),this.div=e.document.createElement("div"),n={direction:Ei(this.cueDiv),writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext",textAlign:"middle"===t.align?"center":t.align,font:i.font,whiteSpace:"pre-line",position:"absolute"},this.applyStyles(n),this.div.appendChild(this.cueDiv);var r=0;switch(t.positionAlign){case"start":r=t.position;break;case"center":r=t.position-t.size/2;break;case"end":r=t.position-t.size}""===t.vertical?this.applyStyles({left:this.formatStyle(r,"%"),width:this.formatStyle(t.size,"%")}):this.applyStyles({top:this.formatStyle(r,"%"),height:this.formatStyle(t.size,"%")}),this.move=function(e){this.applyStyles({top:this.formatStyle(e.top,"px"),bottom:this.formatStyle(e.bottom,"px"),left:this.formatStyle(e.left,"px"),right:this.formatStyle(e.right,"px"),height:this.formatStyle(e.height,"px"),width:this.formatStyle(e.width,"px")}
vendor: 4,315 bytes, line 4715
4715)}}function Ii(e){var t,i,n,r;e.div&&(t=e.div.offsetHeight,i=e.div.offsetWidth,n=e.div.offsetTop,r=(r=e.div.childNodes)&&(r=r[0])&&r.getClientRects&&r.getClientRects(),e=e.div.getBoundingClientRect(),r=r?Math.max(r[0]&&r[0].height||0,e.height/r.length):0),this.left=e.left,this.right=e.right,this.top=e.top||n,this.height=e.height||t,this.bottom=e.bottom||n+(e.height||t),this.width=e.width||i,this.lineHeight=void 0!==r?r:e.lineHeight}function xi(e,t,o,u){var i,n=new Ii(t),r=t.cue,a=function(e){if("number"==typeof e.line&&(e.snapToLines||0<=e.line&&e.line<=100))return e.line;if(!e.track||!e.track.textTrackList||!e.track.textTrackList.mediaElement)return-1;for(var t=e.track,i=t.textTrackList,n=0,r=0;r<i.length&&i[r]!==t;r++)"showing"===i[r].mode&&n++;return-1*++n}(r),s=[];if(r.snapToLines){switch(r.vertical){case"":s=["+y","-y"],i="height";break;case"rl":s=["+x","-x"],i="width";break;case"lr":s=["-x","+x"],i="width"}var l=n.lineHeight,c=l*Math.round(a),d=o[i]+l,h=s[0];Math.abs(c)>d&&(c=c<0?-1:1,c*=Math.ceil(d/l)*l),a<0&&(c+=""===r.vertical?o.height:o.width,s=s.reverse()),n.move(h,c)}else{var p=n.lineHeight/o.height*100;switch(r.lineAlign){case"center":a-=p/2;break;case"end":a-=p}switch(r.vertical){case"":t.applyStyles({top:t.formatStyle(a,"%")});break;case"rl":t.applyStyles({left:t.formatStyle(a,"%")});break;case"lr":t.applyStyles({right:t.formatStyle(a,"%")})}s=["+y","-x","+x","-y"],n=new Ii(t)}n=function(e,t){for(var i,n=new Ii(e),r=1,a=0;a<t.length;a++){for(;e.overlapsOppositeAxis(o,t[a])||e.within(o)&&e.overlapsAny(u);)e.move(t[a]);if(e.within(o))return e;var s=e.intersectPercentage(o);s<r&&(i=new Ii(e),r=s),e=new Ii(n)}return i||n}(n,s);t.move(n.toCSSCompatValues(o))}function Ai(){}ki.prototype.applyStyles=function(e,t){for(var i in t=t||this.div,e)e.hasOwnProperty(i)&&(t.style[i]=e[i])},ki.prototype.formatStyle=function(e,t){return 0===e?0:e+t},(Ci.prototype=ci(ki.prototype)).constructor=Ci,Ii.prototype.move=function(e,t){switch(t=void 0!==t?t:this.lineHeight,e){case"+x":this.left+=t,this.right+=t;break;case"-x":this.left-=t,this.right-=t;break;case"+y":this.top+=t,this.bottom+=t;break;case"-y":this.top-=t,this.bottom-=t}},Ii.prototype.overlaps=function(e){return this.left<e.right&&this.right>e.left&&this.top<e.bottom&&this.bottom>e.top},Ii.prototype.overlapsAny=function(e){for(var t=0;t<e.length;t++)if(this.overlaps(e[t]))return!0;return!1},Ii.prototype.within=function(e){return this.top>=e.top&&this.bottom<=e.bottom&&this.left>=e.left&&this.right<=e.right},Ii.prototype.overlapsOppositeAxis=function(e,t){switch(t){case"+x":return this.left<e.left;case"-x":return this.right>e.right;case"+y":return this.top<e.top;case"-y":return this.bottom>e.bottom}},Ii.prototype.intersectPercentage=function(e){return Math.max(0,Math.min(this.right,e.right)-Math.max(this.left,e.left))*Math.max(0,Math.min(this.bottom,e.bottom)-Math.max(this.top,e.top))/(this.height*this.width)},Ii.prototype.toCSSCompatValues=function(e){return{top:this.top-e.top,bottom:e.bottom-this.bottom,left:this.left-e.left,right:e.right-this.right,height:this.height,width:this.width}},Ii.getSimpleBoxPosition=function(e){var t=e.div?e.div.offsetHeight:e.tagName?e.offsetHeight:0,i=e.div?e.div.offsetWidth:e.tagName?e.offsetWidth:0,n=e.div?e.div.offsetTop:e.tagName?e.offsetTop:0;return{left:(e=e.div?e.div.getBoundingClientRect():e.tagName?e.getBoundingClientRect():e).left,right:e.right,top:e.top||n,height:e.height||t,bottom:e.bottom||n+(e.height||t),width:e.width||i}},Ai.StringDecoder=function(){return{decode:function(e){if(!e)return"";if("string"!=typeof e)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(e))}}},Ai.convertCueToDOMTree=function(e,t){return e&&t?Si(e,t):null};Ai.processCues=function(n,r,e){if(!n||!r||!e)return null;for(;e.firstChild;)e.removeChild(e.firstChild);var a=n.document.createElement("div");if(a.style.position="absolute",a.style.left="0",a.style.right="0",a.style.top="0",a.style.bottom="0",a.style.margin="1.5%",e.appendChild(a),function(e){for(var t=0;t<e.length;t++)if(e[t].hasBeenReset||!e[t].displayState)return 1}(r)){var s=[],o=Ii.getSimpleBoxPosition(a),u={font:Math.round(.05*o.height*100)/100+"px sans-serif"};!function(){for(var e,t,i=0;i<r.length;i++)t=r[i],e=new Ci(n,t,u),a.appendChild(e.div),xi(0,e,o,s),t.dis
vendor: 3,752 bytes, line 4715
4715playState=e.div,s.push(Ii.getSimpleBoxPosition(e))}()}else for(var t=0;t<r.length;t++)a.appendChild(r[t].displayState)},(Ai.Parser=function(e,t,i){i||(i=t,t={}),t=t||{},this.window=e,this.vttjs=t,this.state="INITIAL",this.buffer="",this.decoder=i||new TextDecoder("utf8"),this.regionList=[]}).prototype={reportOrThrowError:function(e){if(!(e instanceof hi))throw e;this.onparsingerror&&this.onparsingerror(e)},parse:function(e){var n=this;function t(){for(var e=n.buffer,t=0;t<e.length&&"\r"!==e[t]&&"\n"!==e[t];)++t;var i=e.substr(0,t);return"\r"===e[t]&&++t,"\n"===e[t]&&++t,n.buffer=e.substr(t),i}function i(e){e.match(/X-TIMESTAMP-MAP/)?mi(e,function(e,t){var i;"X-TIMESTAMP-MAP"===e&&(t=t,i=new fi,mi(t,function(e,t){switch(e){case"MPEGT":i.integer(e+"S",t);break;case"LOCA":i.set(e+"L",pi(t))}},/[^\d]:/,/,/),n.ontimestampmap&&n.ontimestampmap({MPEGTS:i.get("MPEGTS"),LOCAL:i.get("LOCAL")}))},/=/):mi(e,function(e,t){var r;"Region"===e&&(t=t,r=new fi,mi(t,function(e,t){switch(e){case"id":r.set(e,t);break;case"width":r.percent(e,t);break;case"lines":r.integer(e,t);break;case"regionanchor":case"viewportanchor":var i=t.split(",");if(2!==i.length)break;var n=new fi;if(n.percent("x",i[0]),n.percent("y",i[1]),!n.has("x")||!n.has("y"))break;r.set(e+"X",n.get("x")),r.set(e+"Y",n.get("y"));break;case"scroll":r.alt(e,t,["up"])}},/=/,/\s/),r.has("id")&&((t=new(n.vttjs.VTTRegion||n.window.VTTRegion)).width=r.get("width",100),t.lines=r.get("lines",3),t.regionAnchorX=r.get("regionanchorX",0),t.regionAnchorY=r.get("regionanchorY",100),t.viewportAnchorX=r.get("viewportanchorX",0),t.viewportAnchorY=r.get("viewportanchorY",100),t.scroll=r.get("scroll",""),n.onregion&&n.onregion(t),n.regionList.push({id:r.get("id"),region:t})))},/:/)}e&&(n.buffer+=n.decoder.decode(e,{stream:!0}));try{if("INITIAL"===n.state){if(!/\r\n|\n/.test(n.buffer))return this;var r,a=(r=t()).match(/^WEBVTT([ \t].*)?$/);if(!a||!a[0])throw new hi(hi.Errors.BadSignature);n.state="HEADER"}for(var s=!1;n.buffer;){if(!/\r\n|\n/.test(n.buffer))return this;switch(s?s=!1:r=t(),n.state){case"HEADER":/:/.test(r)?i(r):r||(n.state="ID");continue;case"NOTE":r||(n.state="ID");continue;case"ID":if(/^NOTE($|[ \t])/.test(r)){n.state="NOTE";break}if(!r)continue;n.cue=new(n.vttjs.VTTCue||n.window.VTTCue)(0,0,"");try{n.cue.align="center"}catch(e){n.cue.align="middle"}if(n.state="CUE",-1===r.indexOf("--\x3e")){n.cue.id=r;continue}case"CUE":try{gi(r,n.cue,n.regionList)}catch(e){n.reportOrThrowError(e),n.cue=null,n.state="BADCUE";continue}n.state="CUETEXT";continue;case"CUETEXT":var o=-1!==r.indexOf("--\x3e");if(!r||o&&(s=!0)){n.oncue&&n.oncue(n.cue),n.cue=null,n.state="ID";continue}n.cue.text&&(n.cue.text+="\n"),n.cue.text+=r.replace(/\u2028/g,"\n").replace(/u2029/g,"\n");continue;case"BADCUE":r||(n.state="ID");continue}}}catch(e){n.reportOrThrowError(e),"CUETEXT"===n.state&&n.cue&&n.oncue&&n.oncue(n.cue),n.cue=null,n.state="INITIAL"===n.state?"BADWEBVTT":"BADCUE"}return this},flush:function(){var t=this;try{if(t.buffer+=t.decoder.decode(),!t.cue&&"HEADER"!==t.state||(t.buffer+="\n\n",t.parse()),"INITIAL"===t.state)throw new hi(hi.Errors.BadSignature)}catch(e){t.reportOrThrowError(e)}return t.onflush&&t.onflush(),this}};var Pi=Ai,Li={"":1,lr:1,rl:1},Di={start:1,center:1,end:1,left:1,right:1,auto:1,"line-left":1,"line-right":1};function Oi(e){return"string"==typeof e&&(!!Di[e.toLowerCase()]&&e.toLowerCase())}function Ri(e,t,i){this.hasBeenReset=!1;var n="",r=!1,a=e,s=t,o=i,u=null,l="",c=!0,d="auto",h="start",p="auto",f="auto",m=100,g="center";Object.defineProperties(this,{id:{enumerable:!0,get:function(){return n},set:function(e){n=""+e}},pauseOnExit:{enumerable:!0,get:function(){return r},set:function(e){r=!!e}},startTime:{enumerable:!0,get:function(){return a}
vendor: 2,805 bytes, line 4715
4715,set:function(e){if("number"!=typeof e)throw new TypeError("Start time must be set to a number.");a=e,this.hasBeenReset=!0}},endTime:{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e)throw new TypeError("End time must be set to a number.");s=e,this.hasBeenReset=!0}},text:{enumerable:!0,get:function(){return o},set:function(e){o=""+e,this.hasBeenReset=!0}},region:{enumerable:!0,get:function(){return u},set:function(e){u=e,this.hasBeenReset=!0}},vertical:{enumerable:!0,get:function(){return l},set:function(e){e="string"==typeof(e=e)&&(!!Li[e.toLowerCase()]&&e.toLowerCase());if(!1===e)throw new SyntaxError("Vertical: an invalid or illegal direction string was specified.");l=e,this.hasBeenReset=!0}},snapToLines:{enumerable:!0,get:function(){return c},set:function(e){c=!!e,this.hasBeenReset=!0}},line:{enumerable:!0,get:function(){return d},set:function(e){if("number"!=typeof e&&"auto"!==e)throw new SyntaxError("Line: an invalid number or illegal string was specified.");d=e,this.hasBeenReset=!0}},lineAlign:{enumerable:!0,get:function(){return h},set:function(e){e=Oi(e);e&&(h=e,this.hasBeenReset=!0)}},position:{enumerable:!0,get:function(){return p},set:function(e){if(e<0||100<e)throw new Error("Position must be between 0 and 100.");p=e,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return f},set:function(e){e=Oi(e);e&&(f=e,this.hasBeenReset=!0)}},size:{enumerable:!0,get:function(){return m},set:function(e){if(e<0||100<e)throw new Error("Size must be between 0 and 100.");m=e,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return g},set:function(e){e=Oi(e);if(!e)throw new SyntaxError("align: an invalid or illegal alignment string was specified.");g=e,this.hasBeenReset=!0}}}),this.displayState=void 0}Ri.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var Mi=Ri,Ni={"":!0,up:!0};function Ui(e){return"number"==typeof e&&0<=e&&e<=100}function Bi(){var t=100,i=3,n=0,r=100,a=0,s=100,o="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return t},set:function(e){if(!Ui(e))throw new Error("Width must be between 0 and 100.");t=e}},lines:{enumerable:!0,get:function(){return i},set:function(e){if("number"!=typeof e)throw new TypeError("Lines must be set to a number.");i=e}},regionAnchorY:{enumerable:!0,get:function(){return r},set:function(e){if(!Ui(e))throw new Error("RegionAnchorX must be between 0 and 100.");r=e}},regionAnchorX:{enumerable:!0,get:function(){return n},set:function(e){if(!Ui(e))throw new Error("RegionAnchorY must be between 0 and 100.");n=e}},viewportAnchorY:{enumerable:!0,get:function(){return s},set:function(e){if(!Ui(e))throw new Error("ViewportAnchorY must be between 0 and 100.");s=e}},viewportAnchorX:{enumerable:!0,get:function(){return a}
vendor: 8,367 bytes, line 4715
4715,set:function(e){if(!Ui(e))throw new Error("ViewportAnchorX must be between 0 and 100.");a=e}},scroll:{enumerable:!0,get:function(){return o},set:function(e){e="string"==typeof(e=e)&&(!!Ni[e.toLowerCase()]&&e.toLowerCase());!1===e||(o=e)}}})}var Fi=m(function(e){e=e.exports={WebVTT:Pi,VTTCue:Mi,VTTRegion:Bi};Kt.vttjs=e,Kt.WebVTT=e.WebVTT;var t=e.VTTCue,i=e.VTTRegion,n=Kt.VTTCue,r=Kt.VTTRegion;e.shim=function(){Kt.VTTCue=t,Kt.VTTRegion=i},e.restore=function(){Kt.VTTCue=n,Kt.VTTRegion=r},Kt.VTTCue||e.shim()});Fi.WebVTT,Fi.VTTCue,Fi.VTTRegion;var ji=function(n){function i(t,e){var i;return void 0===e&&(e=function(){}),(t=void 0===t?{}:t).reportTouchActivity=!1,(i=n.call(this,null,t,e)||this).onDurationChange_=function(e){return i.onDurationChange(e)},i.trackProgress_=function(e){return i.trackProgress(e)},i.trackCurrentTime_=function(e){return i.trackCurrentTime(e)},i.stopTrackingCurrentTime_=function(e){return i.stopTrackingCurrentTime(e)},i.disposeSourceHandler_=function(e){return i.disposeSourceHandler(e)},i.hasStarted_=!1,i.on("playing",function(){this.hasStarted_=!0}),i.on("loadstart",function(){this.hasStarted_=!1}),oi.names.forEach(function(e){e=oi[e];t&&t[e.getterName]&&(i[e.privateName]=t[e.getterName])}),i.featuresProgressEvents||i.manualProgressOn(),i.featuresTimeupdateEvents||i.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach(function(e){!1===t["native"+e+"Tracks"]&&(i["featuresNative"+e+"Tracks"]=!1)}),!1===t.nativeCaptions||!1===t.nativeTextTracks?i.featuresNativeTextTracks=!1:!0!==t.nativeCaptions&&!0!==t.nativeTextTracks||(i.featuresNativeTextTracks=!0),i.featuresNativeTextTracks||i.emulateTextTracks(),i.preloadTextTracks=!1!==t.preloadTextTracks,i.autoRemoteTextTracks_=new oi.text.ListClass,i.initTrackListeners(),t.nativeControlsForTouch||i.emitTapEvents(),i.constructor&&(i.name_=i.constructor.name||"Unknown Tech"),i}mt(i,n);var e=i.prototype;return e.triggerSourceset=function(e){var t=this;this.isReady_||this.one("ready",function(){return t.setTimeout(function(){return t.triggerSourceset(e)},1)}),this.trigger({src:e,type:"sourceset"})},e.manualProgressOn=function(){this.on("durationchange",this.onDurationChange_),this.manualProgress=!0,this.one("ready",this.trackProgress_)},e.manualProgressOff=function(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange_)},e.trackProgress=function(e){this.stopTrackingProgress(),this.progressInterval=this.setInterval(Ve(this,function(){var e=this.bufferedPercent();this.bufferedPercent_!==e&&this.trigger("progress"),1===(this.bufferedPercent_=e)&&this.stopTrackingProgress()}),500)},e.onDurationChange=function(e){this.duration_=this.duration()},e.buffered=function(){return vt(0,0)},e.bufferedPercent=function(){return _t(this.buffered(),this.duration_)},e.stopTrackingProgress=function(){this.clearInterval(this.progressInterval)},e.manualTimeUpdatesOn=function(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime_),this.on("pause",this.stopTrackingCurrentTime_)},e.manualTimeUpdatesOff=function(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime_),this.off("pause",this.stopTrackingCurrentTime_)},e.trackCurrentTime=function(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval(function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},250)},e.stopTrackingCurrentTime=function(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.dispose=function(){this.clearTracks(ai.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),n.prototype.dispose.call(this)},e.clearTracks=function(e){var r=this;(e=[].concat(e)).forEach(function(e){for(var t=r[e+"Tracks"]()||[],i=t.length;i--;){var n=t[i];"text"===e&&r.removeRemoteTextTrack(n),t.removeTrack(n)}})},e.cleanupAutoTextTracks=function(){for(var e=this.autoRemoteTextTracks_||[],t=e.length;t--;){var i=e[t];this.removeRemoteTextTrack(i)}},e.reset=function(){},e.crossOrigin=function(){},e.setCrossOrigin=function(){},e.error=function(e){return void 0!==e&&(this.error_=new bt(e),this.trigger("error")),this.error_},e.played=function(){return this.hasStarted_?vt(0,0):vt()},e.play=function(){},e.setScrubbing=function(){},e.scrubbing=function(){},e.setCurrentTime=function(){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.initTrackListeners=function(){var r=this;ai.names.forEach(function(e){function t(){r.trigger(e+"trackchange")}var i=ai[e],n=r[i.getterName]();n.addEventListener("removetrack",t),n.addEventListener("addtrack",t),r.on("dispose",function(){n.removeEventListener("removetrack",t),n.removeEventListener("addtrack",t)})})},e.addWebVttScript_=function(){var e,t=this;window.WebVTT||(document.body.contains(this.el())?!this.options_["vtt.js"]&&S(Fi)&&0<Object.keys(Fi).length?this.trigger("vttjsloaded"):((e=document.createElement("script")).src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",e.onload=function(){t.trigger("vttjsloaded")},e.onerror=function(){t.trigger("vttjserror")},this.on("dispose",function(){e.onload=null,e.onerror=null}),window.WebVTT=!0,this.el().parentNode.appendChild(e)):this.ready(this.addWebVttScript_))},e.emulateTextTracks=function(){function t(e){return n.addTrack(e.track)}function i(e){return n.removeTrack(e.track)}var e=this,n=this.textTracks(),r=this.remoteTextTracks();r.on("addtrack",t),r.on("removetrack",i),this.addWebVttScript_();function a(){return e.trigger("texttrackchange")}function s(){a();for(var e=0;e<n.length;e++){var t=n[e];t.removeEventListener("cuechange",a),"showing"===t.mode&&t.addEventListener("cuechange",a)}}s(),n.addEventListener("change",s),n.addEventListener("addtrack",s),n.addEventListener("removetrack",s),this.on("dispose",function(){r.off("addtrack",t),r.off("removetrack",i),n.removeEventListener("change",s),n.removeEventListener("addtrack",s),n.removeEventListener("removetrack",s);for(var e=0;e<n.length;e++)n[e].removeEventListener("cuechange",a)})},e.addTextTrack=function(e,t,i){if(!e)throw new Error("TextTrack kind is required but was not provided");return function(e,t,i,n,r){void 0===r&&(r={});var a=e.textTracks();return r.kind=t,i&&(r.label=i),n&&(r.language=n),r.tech=e,r=new oi.text.TrackClass(r),a.addTrack(r),r}(this,e,t,i)},e.createRemoteTextTrack=function(e){e=lt(e,{tech:this});return new si.remoteTextEl.TrackClass(e)},e.addRemoteTextTrack=function(e,t){var i=this,n=this.createRemoteTextTrack(e=void 0===e?{}:e);return!0!==t&&!1!==t&&(h.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'),t=!0),this.remoteTextTrackEls().addTrackElement_(n),this.remoteTextTracks().addTrack(n.track),!0!==t&&this.ready(function(){return i.autoRemoteTextTracks_.addTrack(n.track)}),n},e.removeRemoteTextTrack=function(e){var t=this.remoteTextTrackEls().getTrackElementByTrack_(e);this.remoteTextTrackEls().removeTrackElement_(t),this.remoteTextTracks().removeTrack(e),this.autoRemoteTextTracks_.removeTrack(e)},e.getVideoPlaybackQuality=function(){return{}},e.requestPictureInPicture=function(){var e=this.options_.Promise||window.Promise;if(e)return e.reject()},e.disablePictureInPicture=function(){return!0},e.setDisablePictureInPicture=function(){},e.setPoster=function(){},e.playsinline=function(){},e.setPlaysinline=function(){},e.overrideNativeAudioTracks=function(){},e.overrideNativeVideoTracks=function(){},e.canPlayType=function(){return""},i.canPlayType=function(){return""},i.canPlaySource=function(e,t){return i.canPlayType(e.type)},i.isTech=function(e){return e.prototype instanceof i||e instanceof i||e===i},i.registerTech=function(e,t){if(i.techs_||(i.techs_={}),!i.isTech(t))throw new Error("Tech "+e+" must be a Tech");if(!i.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!i.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return e=ut(e),i.techs_[e]=t,i.techs_[ot(e)]=t,"Tech"!==e&&i.defaultTechOrder_.push(e),t},i.getTech=function(e){if(e)return i.techs_&&i.techs_[e]?i.techs_[e]:(e=ut(e),window&&window.videojs&&window.videojs[e]?(h.warn("The "+e+" tech w
4715as added to the videojs object when it should be registered using videojs.registerTech(name, tech)"),window.videojs[e]):void 0)},i}(pt);oi.names.forEach(function(e){var t=oi[e];ji.prototype[t.getterName]=function(){return this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName]}}),ji.prototype.featuresVolumeControl=!0,ji.prototype.featuresMuteControl=!0,ji.prototype.featuresFullscreenResize=!1,ji.prototype.featuresPlaybackRate=!1,ji.prototype.featuresProgressEvents=!1,ji.prototype.featuresSourceset=!1,ji.prototype.featuresTimeupdateEvents=!1,ji.prototype.featuresNativeTextTracks=!1,ji.withSourceHandlers=function(r){r.registerSourceHandler=function(e,t){var i=(i=r.sourceHandlers)||(r.sourceHandlers=[]);void 0===t&&(t=i.length),i.splice(t,0,e)},r.canPlayType=function(e){for(var t,i=r.sourceHandlers||[],n=0;n<i.length;n++)if(t=i[n].canPlayType(e))return t;return""},r.selectSourceHandler=function(e,t){for(var i=r.sourceHandlers||[],n=0;n<i.length;n++)if(i[n].canHandleSource(e,t))return i[n];return null},r.canPlaySource=function(e,t){var i=r.selectSourceHandler(e,t);return i?i.canHandleSource(e,t):""};["seekable","seeking","duration"].forEach(function(e){var t=this[e];"function"==typeof t&&(this[e]=function(){return this.sourceHandler_&&this.sourceHandler_[e]?this.sourceHandler_[e].apply(this.sourceHandler_,arguments):t.apply(this,arguments)})},r.prototype),r.prototype.setSource=function(e){var t=r.selectSourceHandler(e,this.options_);t||(r.nativeSourceHandler?t=r.nativeSourceHandler:h.error("No source handler found for the current source.")),this.disposeSourceHandler(),this.off("dispose",this.disposeSourceHandler_),t!==r.nativeSourceHandler&&(this.currentSource_=e),this.sourceHandler_=t.handleSource(e,this,this.options_),this.one("dispose",this.disposeSourceHandler_)},r.prototype.disposeSourceHandler=function(){this.currentSource_&&(this.clearTracks(["audio","video"]),this.currentSource_=null),this.cleanupAutoTextTracks(),this.sourceHandler_&&(this.sourceHandler_.dispose&&this.sourceHandler_.dispose(),this.sourceHandler_=null)}},pt.registerComponent("Tech",ji),ji.registerTech("Tech",ji),ji.defaultTechOrder_=[];var Hi={},qi={},Vi={};function Wi(e,t,i){e.setTimeout(function(){return function i(n,e,r,a,s,o){void 0===n&&(n={});void 0===e&&(e=[]);void 0===s&&(s=[]);void 0===o&&(o=!1);var t=e,e=t[0],u=t.slice(1);if("string"==typeof e)i(n,Hi[e],r,a,s,o);else if(e){var l=Qi(a,e);if(!l.setSource)return s.push(l),i(n,u,r,a,s,o);l.setSource(b({},n),function(e,t){return e?i(n,u,r,a,s,o):(s.push(l),void i(t,n.type===t.type?u:Hi[t.type],r,a,s,o))})}else u.length?i(n,u,r,a,s,o):o?r(n,s):i(n,Hi["*"],r,a,s,!0)}(t,Hi[t.type],i,e)},1)}function Gi(e,t,i,n){void 0===n&&(n=null);var r="call"+ut(i),r=e.reduce(Yi(r),n),n=r===Vi,r=n?null:t[i](r);return function(e,t,i,n){for(var r=e.length-1;0<=r;r--){var a=e[r];a[t]&&a[t](n,i)}}(e,i,r,n),r}var zi={buffered:1,currentTime:1,duration:1,muted:1,played:1,paused:1,seekable:1,volume:1,ended:1},Xi={setCurrentTime:1,setMuted:1,setVolume:1},Ki={play:1,pause:1};function Yi(i){return function(e,t){return e===Vi?Vi:t[i]?t[i](e):e}}function Qi(e,t){var i=qi[e.id()],n=null;if(null==i)return n=t(e),qi[e.id()]=[[t,n]],n;for(var r=0;r<i.length;r++){var a=i[r],s=a[0],a=a[1];s===t&&(n=a)}return null===n&&(n=t(e),i.push([t,n])),n}function $i(e){return e=Nt(e=void 0===e?"":e),Zi[e.toLowerCase()]||""}function Ji(e){var t;return e=Array.isArray(e)?(t=[],e.forEach(function(e){e=Ji(e),Array.isArray(e)?t=t.concat(e):T(e)&&t.push(e)}),t):"string"==typeof e&&e.trim()?[en({src:e})]:T(e)&&"string"==typeof e.src&&e.src&&e.src.trim()?[en(e)]:[]}var Zi={opus:"video/ogg",ogv:"video/ogg",mp4:"video/mp4",mov:"video/mp4",m4v:"video/mp4",mkv:"video/x-matroska",m4a:"audio/mp4",mp3:"audio/mpeg",aac:"audio/aac",caf:"audio/x-caf",flac:"audio/flac",oga:"audio/ogg",wav:"audio/wav",m3u8:"application/x-mpegURL",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"};function en(e){var t;return e.type||(t=$i(e.src))&&(e.type=t),e}I=function(u){function e(e,t,i){var n=lt({createEl:!1},t),i=u.call(this,e,n,i)||this;if(t.playerOptions.sources&&0!==t.playerOptions.sources.length)e.src(t.playerOptions.sources);else for(var r=0,a=t.playerOptions.techOrder;r<a.length;r++){var s=ut(a[r]),o=ji.getTech(s);if((o=!s?pt.getComponent(s):o)&&o.isSupported()){e.loadTech_(s);break}}return i}return mt(e,u),e}(pt);pt.registerComponent("MediaLoader",I);C=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseOver_=function(e){return i.handleMouseOver(e)},i.handleMouseOut_=function(e){return i.handleMouseOut(e)},i.handleClick_=function(e){return i.handleClick(e)},i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.emitTapEvents(),i.enable(),i}mt(e,n);var t=e.prototype;return t.createEl=function(e,t,i){void 0===e&&(e="div"),void 0===t&&(t={}),void 0===i&&(i={}),t=b({className:this.buildCSSClass(),tabIndex:0},t),"button"===e&&h.error("Creating a ClickableComponent with an HTML element of "+e+" is not supported; use a Button instead."),i=b({role:"button"},i),this.tabIndex_=t.tabIndex;i=$(e,t,i);return i.appendChild($("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(i),i},t.dispose=function(){this.controlTextEl_=null,n.prototype.dispose.call(this)},t.createControlTextEl=function(e){return this.controlTextEl_=$("span",{className:"vjs-control-text"},{"aria-live":"polite"}),e&&e.appendChild(this.controlTextEl_),this.controlText(this.controlText_,e),this.controlTextEl_},t.controlText=function(e,t){if(void 0===t&&(t=this.el()),void 0===e)return this.controlText_||"Need Text";var i=this.localize(e);this.controlText_=e,J(this.controlTextEl_,i),this.nonIconControl||this.player_.options_.noUITitleAttributes||t.setAttribute("title",i)},t.buildCSSClass=function(){return"vjs-control vjs-button "+n.prototype.buildCSSClass.call(this)},t.enable=function(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),"undefined"!=typeof this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick_),this.on("keydown",this.handleKeyDown_))},t.disable=function(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),"undefined"!=typeof this.tabIndex_&&this.el_.removeAttribute("tabIndex"),this.off("mouseover",this.handleMouseOver_),this.off("mouseout",this.handleMouseOut_),this.off(["tap","click"],this.handleClick_),this.off("keydown",this.handleKeyDown_)},t.handleLanguagechange=function(){this.controlText(this.controlText_)},t.handleClick=function(e){this.options_.clickHandler&&this.options_.clickHandler.call(this,arguments)},t.handleKeyDown=function(e){ht.isEventKey(e,"Space")||ht.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):n.prototype.handleKeyDown.call(this,e)},e}(pt);pt.registerComponent("ClickableComponent",C),pt.registerComponent("PosterImage",function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.update(),i.update_=function(e){return i.update(e)},e.on("posterchange",i.update_),i}mt(e,n);var t=e.prototype;return t.dispose=function(){this.player().off("posterchange",this.update_),n.prototype.dispose.call(this)},t.createEl=function(){return $("div",{className:"vjs-poster",tabIndex:-1})},t.update=function(e){var t=this.player().poster();this.setSrc(t),t?this.show():this.hide()},t.setSrc=function(e){this.el_.style.backgroundImage=e?'url("'+e+'")':""},t.handleClick=function(e){var t;this.player_.controls()&&(t=this.player_.usingPlugin("eme")&&this.player_.eme.sessions&&0<this.player_.eme.sessions.length,!this.player_.tech(!0)||(N||O)&&t||this.player_.tech(!0).focus(),this.player_.paused()?Et(this.player_.play()):this.player_.pause())},e}(C));var tn="#222",nn={monospace:"monospace",sansSerif:"sans-serif",serif:"serif",monospaceSansSerif:'"Andale Mono", "Lucida Console", monospace',monospaceSerif:'"Courier New", monospace',proportionalSansSerif:"sans-serif",proportionalSerif:"serif",casual:'"Comic Sans MS", Impact, fantasy',
4715script:'"Monotype Corsiva", cursive',smallcaps:'"Andale Mono", "Lucida Console", monospace, sans-serif'};function rn(e,t){var i;if(4===e.length)i=e[1]+e[1]+e[2]+e[2]+e[3]+e[3];else{if(7!==e.length)throw new Error("Invalid color code provided, "+e+"; must be formatted as e.g. #f0e or #f604e2.");i=e.slice(1)}return"rgba("+parseInt(i.slice(0,2),16)+","+parseInt(i.slice(2,4),16)+","+parseInt(i.slice(4,6),16)+","+t+")"}function an(e,t,i){try{e.style[t]=i}catch(e){return}}pt.registerComponent("TextTrackDisplay",function(a){function e(i,e,t){function n(e){return r.updateDisplay(e)}var r=a.call(this,i,e,t)||this;return i.on("loadstart",function(e){return r.toggleDisplay(e)}),i.on("texttrackchange",n),i.on("loadedmetadata",function(e){return r.preselectTrack(e)}),i.ready(Ve(ft(r),function(){if(i.tech_&&i.tech_.featuresNativeTextTracks)this.hide();else{i.on("fullscreenchange",n),i.on("playerresize",n),window.addEventListener("orientationchange",n),i.on("dispose",function(){return window.removeEventListener("orientationchange",n)});for(var e=this.options_.playerOptions.tracks||[],t=0;t<e.length;t++)this.player_.addRemoteTextTrack(e[t],!0);this.preselectTrack()}})),r}mt(e,a);var t=e.prototype;return t.preselectTrack=function(){for(var e,t,i,n={captions:1,subtitles:1},r=this.player_.textTracks(),a=this.player_.cache_.selectedLanguage,s=0;s<r.length;s++){var o=r[s];a&&a.enabled&&a.language&&a.language===o.language&&o.kind in n?i=o.kind!==a.kind&&i||o:a&&!a.enabled?t=e=i=null:o.default&&("descriptions"!==o.kind||e?o.kind in n&&!t&&(t=o):e=o)}i?i.mode="showing":t?t.mode="showing":e&&(e.mode="showing")},t.toggleDisplay=function(){this.player_.tech_&&this.player_.tech_.featuresNativeTextTracks?this.hide():this.show()},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-text-track-display"},{translate:"yes","aria-live":"off","aria-atomic":"true"})},t.clearDisplay=function(){"function"==typeof window.WebVTT&&window.WebVTT.processCues(window,[],this.el_)},t.updateDisplay=function(){var e=this.player_.textTracks(),t=this.options_.allowMultipleShowingTracks;if(this.clearDisplay(),t){for(var i=[],n=0;n<e.length;++n){var r=e[n];"showing"===r.mode&&i.push(r)}this.updateForTrack(i)}else{for(var a=null,s=null,o=e.length;o--;){var u=e[o];"showing"===u.mode&&("descriptions"===u.kind?a=u:s=u)}s?("off"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","off"),this.updateForTrack(s)):a&&("assertive"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","assertive"),this.updateForTrack(a))}},t.updateDisplayState=function(e){for(var t=this.player_.textTrackSettings.getValues(),i=e.activeCues,n=i.length;n--;){var r,a=i[n];a&&(r=a.displayState,t.color&&(r.firstChild.style.color=t.color),t.textOpacity&&an(r.firstChild,"color",rn(t.color||"#fff",t.textOpacity)),t.backgroundColor&&(r.firstChild.style.backgroundColor=t.backgroundColor),t.backgroundOpacity&&an(r.firstChild,"backgroundColor",rn(t.backgroundColor||"#000",t.backgroundOpacity)),t.windowColor&&(t.windowOpacity?an(r,"backgroundColor",rn(t.windowColor,t.windowOpacity)):r.style.backgroundColor=t.windowColor),t.edgeStyle&&("dropshadow"===t.edgeStyle?r.firstChild.style.textShadow="2px 2px 3px #222, 2px 2px 4px #222, 2px 2px 5px "+tn:"raised"===t.edgeStyle?r.firstChild.style.textShadow="1px 1px #222, 2px 2px #222, 3px 3px "+tn:"depressed"===t.edgeStyle?r.firstChild.style.textShadow="1px 1px #ccc, 0 1px #ccc, -1px -1px #222, 0 -1px "+tn:"uniform"===t.edgeStyle&&(r.firstChild.style.textShadow="0 0 4px #222, 0 0 4px #222, 0 0 4px #222, 0 0 4px "+tn)),t.fontPercent&&1!==t.fontPercent&&(a=window.parseFloat(r.style.fontSize),r.style.fontSize=a*t.fontPercent+"px",r.style.height="auto",r.style.top="auto"),t.fontFamily&&"default"!==t.fontFamily&&("small-caps"===t.fontFamily?r.firstChild.style.fontVariant="small-caps":r.firstChild.style.fontFamily=nn[t.fontFamily]))}},t.updateForTrack=function(e){if(Array.isArray(e)||(e=[e]),"function"==typeof window.WebVTT&&!e.every(function(e){return!e.activeCues})){for(var t=[],i=0;i<e.length;++i)for(var n=e[i],r=0;r<n.activeCues.length;++r)t.push(n.activeCues[r]);window.WebVTT.processCues(window,t,this.el_);for(var a=0;a<e.length;++a){for(var s=e[a],o=0;o<s.activeCues.length;++o){var u=s.activeCues[o].displayState;te(u,"vjs-text-track-cue"),te(u,"vjs-text-track-cue-"+(s.language||a)),s.language&&oe(u,"lang",s.language)}this.player_.textTrackSettings&&this.updateDisplayState(s)}}},e}(pt)),pt.registerComponent("LoadingSpinner",function(i){function e(){return i.apply(this,arguments)||this}return mt(e,i),e.prototype.createEl=function(){var e=this.player_.isAudio(),t=this.localize(e?"Audio Player":"
4715Video Player"),e=$("span",{className:"vjs-control-text",textContent:this.localize("{1} is loading.",[t])}),t=i.prototype.createEl.call(this,"div",{className:"vjs-loading-spinner",dir:"ltr"});return t.appendChild(e),t},e}(pt));var sn=function(t){function e(){return t.apply(this,arguments)||this}mt(e,t);var i=e.prototype;return i.createEl=function(e,t,i){void 0===t&&(t={}),void 0===i&&(i={});i=$("button",t=b({className:this.buildCSSClass()},t),i=b({type:"button"},i));return i.appendChild($("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(i),i},i.addChild=function(e,t){void 0===t&&(t={});var i=this.constructor.name;return h.warn("Adding an actionable (user controllable) child to a Button ("+i+") is not supported; use a ClickableComponent instead."),pt.prototype.addChild.call(this,e,t)},i.enable=function(){t.prototype.enable.call(this),this.el_.removeAttribute("disabled")},i.disable=function(){t.prototype.disable.call(this),this.el_.setAttribute("disabled","disabled")},i.handleKeyDown=function(e){ht.isEventKey(e,"Space")||ht.isEventKey(e,"Enter")?e.stopPropagation():t.prototype.handleKeyDown.call(this,e)},e}(C);pt.registerComponent("Button",sn);Bt=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.mouseused_=!1,i.on("mousedown",function(e){return i.handleMouseDown(e)}),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-big-play-button"},t.handleClick=function(e){var t=this.player_.play();if(this.mouseused_&&e.clientX&&e.clientY){var i=this.player_.usingPlugin("eme")&&this.player_.eme.sessions&&0<this.player_.eme.sessions.length;return Et(t),void(!this.player_.tech(!0)||(N||O)&&i||this.player_.tech(!0).focus())}var i=this.player_.getChild("controlBar"),n=i&&i.getChild("playToggle");n?(i=function(){return n.focus()},wt(t)?t.then(i,function(){}):this.setTimeout(i,1)):this.player_.tech(!0).focus()},t.handleKeyDown=function(e){this.mouseused_=!1,n.prototype.handleKeyDown.call(this,e)},t.handleMouseDown=function(e){this.mouseused_=!0},e}(sn);Bt.prototype.controlText_="Play Video",pt.registerComponent("BigPlayButton",Bt),pt.registerComponent("CloseButton",function(i){function e(e,t){e=i.call(this,e,t)||this;return e.controlText(t&&t.controlText||e.localize("Close")),e}mt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-close-button "+i.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.trigger({type:"close",bubbles:!1})},t.handleKeyDown=function(e){ht.isEventKey(e,"Esc")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):i.prototype.handleKeyDown.call(this,e)},e}(sn));Ft=function(n){function e(e,t){var i=n.call(this,e,t=void 0===t?{}:t)||this;return t.replay=void 0===t.replay||t.replay,i.on(e,"play",function(e){return i.handlePlay(e)}),i.on(e,"pause",function(e){return i.handlePause(e)}),t.replay&&i.on(e,"ended",function(e){return i.handleEnded(e)}),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-play-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.player_.paused()?Et(this.player_.play()):this.player_.pause()},t.handleSeeked=function(e){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(e):this.handlePlay(e)},t.handlePlay=function(e){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")},t.handlePause=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")},t.handleEnded=function(e){var t=this;this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.controlText("Replay"),this.one(this.player_,"seeked",function(e){return t.handleSeeked(e)})},e}(sn);Ft.prototype.controlText_="Play",pt.registerComponent("PlayToggle",Ft);function on(e,t){e=e<0?0:e;var i=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),a=Math.floor(t/60%60),t=Math.floor(t/3600);return(r=0<(r=isNaN(e)||e===1/0?n=i="-":r)||0<t?r+":":"")+(n=((r||10<=a)&&n<10?"0"+n:n)+":")+(i=i<10?"0"+i:i)}var un=on;function ln(e,t){return un(e,t=void 0===t?e:t)}k=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,["timeupdate","ended"],function(e){return i.updateContent(e)}),i.updateTextNode_(),i}mt(e,n);var t=e.prototype;return t.createEl=function(){var e=this.buildCSSClass(),t=n.prototype.createEl.call(this,"div",{className:e+" vjs-time-control vjs-control"}),i=$("span",{className:"vjs-control-text",textContent:this.localize(this.labelText_)+" "},{role:"presentation"});return t.appendChild(i),this.contentEl_=$("span",{className:e+"-display"},{"aria-live":"off",role:"presentation"}),t.appendChild(this.contentEl_),t},t.dispose=function(){this.contentEl_=null,this.textNode_=null,n.prototype.dispose.call(this)},t.updateTextNode_=function(e){var t=this;e=ln(e=void 0===e?0:e),this.formattedTime_!==e&&(this.formattedTime_=e,this.requestNamedAnimationFrame("TimeDisplay#updateTextNode_",function(){var e;t.contentEl_&&((e=t.textNode_)&&t.contentEl_.firstChild!==e&&(e=null,h.warn("TimeDisplay#updateTextnode_: Prevented replacement of text node element since it was no longer a child of this node. Appending a new node instead.")),t.textNode_=document.createTextNode(t.formattedTime_),t.textNode_&&(e?t.contentEl_.replaceChild(t.textNode_,e):t.contentEl_.appendChild(t.textNode_)))}))},t.updateContent=function(e){},e}(pt);k.prototype.labelText_="Time",k.prototype.controlText_="Time",pt.registerComponent("TimeDisplay",k);jt=function(e){function t(){return e.apply(this,arguments)||this}mt(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-current-time"},i.updateContent=function(e){var t=this.player_.ended()?this.player_.duration():this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();this.updateTextNode_(t)},t}(k);jt.prototype.labelText_="Current Time",jt.prototype.controlText_="Current Time",pt.registerComponent("CurrentTimeDisplay",jt);j=function(n){function e(e,t){var i=n.call(this,e,t)||this,t=function(e){return i.updateContent(e)};return i.on(e,"durationchange",t),i.on(e,"loadstart",t),i.on(e,"loadedmetadata",t),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-duration"},t.updateContent=function(e){var t=this.player_.duration();this.updateTextNode_(t)},e}(k);j.prototype.labelText_="Duration",j.prototype.controlText_="Duration",pt.registerComponent("DurationDisplay",j),pt.registerComponent("TimeDivider",function(n){function e(){return n.apply(this,arguments)||this}return mt(e,n),e.prototype.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-time-control vjs-time-divider"},{"aria-hidden":!0}),t=n.prototype.createEl.call(this,"div"),i=n.prototype.createEl.call(this,"span",{textContent:"/"});return t.appendChild(i),e.appendChild(t),e},e}(pt));f=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"durationchange",function(e){return i.updateContent(e)}),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-remaining-time"},t.createEl=function(){var e=n.prototype.createEl.call(this);return!1!==this.options_.displayNegative&&e.insertBefore($("span",{},{"aria-hidden":!0},"-"),this.contentEl_),e},t.updateContent=function(e){var t;"number"==typeof this.player_.duration()&&(t=this.player_.ended()?0:this.player_.remainingTimeDisplay?this.player_.remainingTimeDisplay():this.player_.remainingTime(),this.updateTextNode_(t))},e}(k);f.prototype.labelText_="Remaining Time",f.prototype.controlText_="Remaining Time",pt.registerComponent("RemainingTimeDisplay",f),pt.registerComponent("LiveDisplay",function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.updateShowing(),i.on(i.player(),"durationchange",function(e){return i.updateShowing(e)}),i}mt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-live-control vjs-control"});return this.contentEl_=$("div",{className:"vjs-live-display"},{"aria-live":"off"}),this.contentEl_.appendChild($("span",{className:"vjs-control-text",textContent:this.localize("Stream Type")+" "})),this.contentEl_.appendChild(document.createTextNode(this.localize("LIVE"))),e.appendChild(this.contentEl_),e},t.dispose=function(){this.contentEl_=null,n.prototype.dispose.call(this)},t.updateShowing=function(e){this.player().duration()===1/0?this.show():this.hide()},e}(pt));ui=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.updateLiveEdgeStatus(),i.player_.liveTracker&&(i.updateLiveEdgeStatusHandler_=function(e){return i.updateLiveEdgeStatus(e)},i.on(i.player_.liveTracker,"liveedgechange",i.updateLiveEdgeStatusHandler_)),i}mt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"button",{className:"vjs-seek-to-live-control vjs-control"});return this.textEl_=$("span",{className:"vjs-seek-to-live-text",textContent:this.localize("LIVE")},{"aria-hidden":"true"}),e.appendChild(this.textEl_),e},t.updateLiveEdgeStatus=function(){!this.player_.liveTracker||this.player_.liveTracker.atLiveEdge()?(this.setAttribute("aria-disabled",!0),this.addClass("vjs-at-live-edge"),this.controlText("Seek to live, currently playing live")):(this.setAttribute("aria-disabled",!1),this.removeClass("vjs-at-live-edge"),this.controlText("Seek to live, currently behind live"))},t.handleClick=function(){this.player_.liveTracker.seekToLiveEdge()},t.dispose=function(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_),this.textEl_=null,n.prototype.dispose.call(this)},e}(sn);ui.prototype.controlText_="Seek to live, currently playing live",pt.registerComponent("SeekToLive",ui);function cn(e,t,i){return e=Number(e),Math.min(i,Math.max(t,isNaN(e)?t:e))}li=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseDown_=function(e){return i.handleMouseDown(e)},i.handleMouseUp_=function(e){return i.handleMouseUp(e)},i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.handleClick_=function(e){return i.handleClick(e)},i.handleMouseMove_=function(e){return i.handleMouseMove(e)},i.update_=function(e){return i.update(e)},i.bar=i.getChild(i.options_.barName),i.vertical(!!i.options_.vertical),i.enable(),i}mt(e,n);var t=e.prototype;return t.enabled=function(){return this.enabled_},t.enable=function(){this.enabled()||(this.on("mousedown",this.handleMouseDown_),this.on("touchstart",this.handleMouseDown_),this.on("keydown",this.handleKeyDown_),this.on("click",this.handleClick_),this.on(this.player_,"controlsvisible",this.update),this.playerEvent&&this.on(this.player_,this.playerEvent,this.update),this.removeClass("disabled"),this.setAttribute("tabindex",0),this.enabled_=!0)},t.disable=function(){var e;this.enabled()&&(e=this.bar.el_.ownerDocument,this.off("mousedown",this.handleMouseDown_),this.off("touchstart",this.handleMouseDown_),this.off("keydown",this.handleKeyDown_),this.off("click",this.handleClick_),this.off(this.player_,"controlsvisible",this.update_),this.off(e,"mousemove",this.handleMouseMove_),this.off(e,"mouseup",this.handleMouseUp_),this.off(e,"touchmove",this.handleMouseMove_),this.off(e,"touchend",this.handleMouseUp_),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1)},t.createEl=function(e,t,i){return void 0===i&&(i={}),(t=void 0===t?{}:t).className=t.className+" vjs-slider",t=b({tabIndex:0},t),i=b({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},i),n.prototype.createEl.call(this,e,t,i)},t.handleMouseDown=function(e){var t=this.bar.el_.ownerDocument;"mousedown"===e.type&&e.preventDefault(),"touchstart"!==e.type||R||e.preventDefault(),le(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(t,"mousemove",this.handleMouseMove_),this.on(t,"mouseup",this.handleMouseUp_),this.on(t,"touchmove",this.handleMouseMove_),this.on(t,"touchend",this.handleMouseUp_),this.handleMouseMove(e,!0)},t.handleMouseMove=function(e){},t.handleMouseUp=function(){var e=this.bar.el_.ownerDocument;ce(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(e,"mousemove",this.handleMouseMove_),this.off(e,"mouseup",this.handleMouseUp_),this.off(e,"touchmove",this.handleMouseMove_),this.off(e,"touchend",this.handleMouseUp_),this.update()},t.update=function(){var t=this;if(this.el_&&this.bar){var i=this.getProgress();return i===this.progress_?i:(this.progress_=i,this.requestNamedAnimationFrame("Slider#update",function(){var e=t.vertical()?"height":"width";t.bar.el().style[e]=(100*i).toFixed(2)+"%"}),i)}},t.getProgress=function(){return Number(cn(this.getPercent(),0,1).toFixed(4))},t.calculateDistance=function(e){e=pe(this.el_,e);return this.vertical()?e.y:e.x},t.handleKeyDown=function(e){ht.isEventKey(e,"Left")||ht.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepBack()):ht.isEventKey(e,"Right")||ht.isEventKey(e,"Up")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):n.prototype.handleKeyDown.call(this,e)},t.handleClick=function(e){e.stopPropagation(),e.preventDefault()},t.vertical=function(e){if(void 0===e)return this.vertical_||!1;this.vertical_=!!e,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")},e}(pt);pt.registerComponent("Slider",li);
4715function dn(e,t){return cn(e/t*100,0,100).toFixed(2)+"%"}pt.registerComponent("LoadProgressBar",function(r){function e(e,t){var i=r.call(this,e,t)||this;return i.partEls_=[],i.on(e,"progress",function(e){return i.update(e)}),i}mt(e,r);var t=e.prototype;return t.createEl=function(){var e=r.prototype.createEl.call(this,"div",{className:"vjs-load-progress"}),t=$("span",{className:"vjs-control-text"}),i=$("span",{textContent:this.localize("Loaded")}),n=document.createTextNode(": ");return this.percentageEl_=$("span",{className:"vjs-control-text-loaded-percentage",textContent:"0%"}),e.appendChild(t),t.appendChild(i),t.appendChild(n),t.appendChild(this.percentageEl_),e},t.dispose=function(){this.partEls_=null,this.percentageEl_=null,r.prototype.dispose.call(this)},t.update=function(e){var l=this;this.requestNamedAnimationFrame("LoadProgressBar#update",function(){var e=l.player_.liveTracker,t=l.player_.buffered(),e=e&&e.isLive()?e.seekableEnd():l.player_.duration(),i=l.player_.bufferedEnd(),n=l.partEls_,e=dn(i,e);l.percent_!==e&&(l.el_.style.width=e,J(l.percentageEl_,e),l.percent_=e);for(var r=0;r<t.length;r++){var a=t.start(r),s=t.end(r),o=n[r];o||(o=l.el_.appendChild($()),n[r]=o),o.dataset.start===a&&o.dataset.end===s||(o.dataset.start=a,o.dataset.end=s,o.style.left=dn(a,i),o.style.width=dn(s-a,i))}for(var u=n.length;u>t.length;u--)l.el_.removeChild(n[u-1]);n.length=t.length})},e}(pt)),pt.registerComponent("TimeTooltip",function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=We(Ve(ft(t),t.update),30),t}mt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})},t.update=function(e,t,i){var n=he(this.el_),r=de(this.player_.el()),a=e.width*t;r&&n&&(t=e.left-r.left+a,r=e.width-a+(r.right-e.right),t<(e=n.width/2)?e+=e-t:r<e&&(e=r),e<0?e=0:e>n.width&&(e=n.width),e=Math.round(e),this.el_.style.right="-"+e+"px",this.write(i))},t.write=function(e){J(this.el_,e)},t.updateTime=function(n,r,a,s){var o=this;this.requestNamedAnimationFrame("TimeTooltip#updateTime",function(){var e,t,i=o.player_.duration();i=o.player_.liveTracker&&o.player_.liveTracker.isLive()?((t=(e=o.player_.liveTracker.liveWindow())-r*e)<1?"":"-")+ln(t,e):ln(a,i),o.update(n,r,i),s&&s()})},e}(pt));Xt=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=We(Ve(ft(t),t.update),30),t}mt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})},t.update=function(e,t){var i,n=this.getChild("timeTooltip");n&&(i=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),n.updateTime(e,t,i))},e}(pt);Xt.prototype.options_={children:[]},q||A||Xt.prototype.options_.children.push("timeTooltip"),pt.registerComponent("PlayProgressBar",Xt);I=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=We(Ve(ft(t),t.update),30),t}mt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t){var i=this,n=t*this.player_.duration();this.getChild("timeTooltip").updateTime(e,t,n,function(){i.el_.style.left=e.width*t+"px"})},e}(pt);I.prototype.options_={children:["timeTooltip"]},pt.registerComponent("MouseTimeDisplay",I);Bt=function(a){function e(e,t){t=a.call(this,e,t)||this;return t.setEventHandlers_(),t}mt(e,a);var t=e.prototype;return t.setEventHandlers_=function(){var t=this;this.update_=Ve(this,this.update),this.update=We(this.update_,30),this.on(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.enableIntervalHandler_=function(e){return t.enableInterval_(e)},this.disableIntervalHandler_=function(e){return t.disableInterval_(e)},this.on(this.player_,["playing"],this.enableIntervalHandler_),this.on(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.on(document,"visibilitychange",this.toggleVisibility_)},t.toggleVisibility_=function(e){"hidden"===document.visibilityState?(this.cancelNamedAnimationFrame("SeekBar#update"),this.cancelNamedAnimationFrame("Slider#update"),this.disableInterval_(e)):(this.player_.ended()||this.player_.paused()||this.enableInterval_(),this.update())},t.enableInterval_=function(){this.updateInterval||(this.updateInterval=this.setInterval(this.update,30))},t.disableInterval_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&e&&"ended"!==e.type||this.updateInterval&&(this.clearInterval(this.updateInterval),this.updateInterval=null)},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})},t.update=function(e){var n=this;if("hidden"!==document.visibilityState){var r=a.prototype.update.call(this);return this.requestNamedAnimationFrame("SeekBar#update",function(){var e=n.player_.ended()?n.player_.duration():n.getCurrentTime_(),t=n.player_.liveTracker,i=n.player_.duration();
4715t&&t.isLive()&&(i=n.player_.liveTracker.liveCurrentTime()),n.percent_!==r&&(n.el_.setAttribute("aria-valuenow",(100*r).toFixed(2)),n.percent_=r),n.currentTime_===e&&n.duration_===i||(n.el_.setAttribute("aria-valuetext",n.localize("progress bar timing: currentTime={1} duration={2}",[ln(e,i),ln(i,i)],"{1} of {2}")),n.currentTime_=e,n.duration_=i),n.bar&&n.bar.update(de(n.el()),n.getProgress())}),r}},t.userSeek_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&this.player_.liveTracker.nextSeekedFromUser(),this.player_.currentTime(e)},t.getCurrentTime_=function(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()},t.getPercent=function(){var e,t=this.getCurrentTime_(),i=this.player_.liveTracker;return i&&i.isLive()?(e=(t-i.seekableStart())/i.liveWindow(),i.atLiveEdge()&&(e=1)):e=t/this.player_.duration(),e},t.handleMouseDown=function(e){_e(e)&&(e.stopPropagation(),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),a.prototype.handleMouseDown.call(this,e))},t.handleMouseMove=function(e,t){if(void 0===t&&(t=!1),_e(e)){t||this.player_.scrubbing()||this.player_.scrubbing(!0);var i=this.calculateDistance(e),n=this.player_.liveTracker;if(n&&n.isLive()){if(.99<=i)return void n.seekToLiveEdge();var r,t=n.seekableStart(),e=n.liveCurrentTime();if((r=(r=e<=(r=t+i*n.liveWindow())?e:r)<=t?t+.1:r)===1/0)return}else(r=i*this.player_.duration())===this.player_.duration()&&(r-=.1);this.userSeek_(r)}},t.enable=function(){a.prototype.enable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.show()},t.disable=function(){a.prototype.disable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.hide()},t.handleMouseUp=function(e){a.prototype.handleMouseUp.call(this,e),e&&e.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying?Et(this.player_.play()):this.update_()},t.stepForward=function(){this.userSeek_(this.player_.currentTime()+5)},t.stepBack=function(){this.userSeek_(this.player_.currentTime()-5)},t.handleAction=function(e){this.player_.paused()?this.player_.play():this.player_.pause()},t.handleKeyDown=function(e){var t,i=this.player_.liveTracker;ht.isEventKey(e,"Space")||ht.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.handleAction(e)):ht.isEventKey(e,"Home")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(0)):ht.isEventKey(e,"End")?(e.preventDefault(),e.stopPropagation(),i&&i.isLive()?this.userSeek_(i.liveCurrentTime()):this.userSeek_(this.player_.duration())):/^[0-9]$/.test(ht(e))?(e.preventDefault(),e.stopPropagation(),t=10*(ht.codes[ht(e)]-ht.codes[0])/100,i&&i.isLive()?this.userSeek_(i.seekableStart()+i.liveWindow()*t):this.userSeek_(this.player_.duration()*t)):ht.isEventKey(e,"PgDn")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(this.player_.currentTime()-60)):ht.isEventKey(e,"PgUp")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(this.player_.currentTime()+60)):a.prototype.handleKeyDown.call(this,e)}
4715,t.dispose=function(){this.disableInterval_(),this.off(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.update),this.off(this.player_,["playing"],this.enableIntervalHandler_),this.off(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in document&&"visibilityState"in document&&this.off(document,"visibilitychange",this.toggleVisibility_),a.prototype.dispose.call(this)},e}(li);Bt.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},q||A||Bt.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),pt.registerComponent("SeekBar",Bt);Ft=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseMove=We(Ve(ft(i),i.handleMouseMove),30),i.throttledHandleMouseSeek=We(Ve(ft(i),i.handleMouseSeek),30),i.handleMouseUpHandler_=function(e){return i.handleMouseUp(e)},i.handleMouseDownHandler_=function(e){return i.handleMouseDown(e)},i.enable(),i}mt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-control vjs-control"})},t.handleMouseMove=function(e){var t,i,n,r,a=this.getChild("seekBar");a&&(t=a.getChild("playProgressBar"),i=a.getChild("mouseTimeDisplay"),(t||i)&&(r=he(n=a.el()),e=pe(n,e).x,e=cn(e,0,1),i&&i.update(r,e),t&&t.update(r,a.getProgress())))},t.handleMouseSeek=function(e){var t=this.getChild("seekBar");t&&t.handleMouseMove(e)},t.enabled=function(){return this.enabled_},t.disable=function(){var e;
4715this.children().forEach(function(e){return e.disable&&e.disable()}),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDownHandler_),this.off(this.el_,"mousemove",this.handleMouseMove),this.removeListenersAddedOnMousedownAndTouchstart(),this.addClass("disabled"),this.enabled_=!1,this.player_.scrubbing()&&(e=this.getChild("seekBar"),this.player_.scrubbing(!1),e.videoWasPlaying&&Et(this.player_.play())))},t.enable=function(){this.children().forEach(function(e){return e.enable&&e.enable()}),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDownHandler_),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)},t.removeListenersAddedOnMousedownAndTouchstart=function(){var e=this.el_.ownerDocument;this.off(e,"mousemove",this.throttledHandleMouseSeek),this.off(e,"touchmove",this.throttledHandleMouseSeek),this.off(e,"mouseup",this.handleMouseUpHandler_),this.off(e,"touchend",this.handleMouseUpHandler_)},t.handleMouseDown=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseDown(e),this.on(t,"mousemove",this.throttledHandleMouseSeek),this.on(t,"touchmove",this.throttledHandleMouseSeek),this.on(t,"mouseup",this.handleMouseUpHandler_),this.on(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseUp=function(e){var t=this.getChild("seekBar");t&&t.handleMouseUp(e),this.removeListenersAddedOnMousedownAndTouchstart()},e}(pt);Ft.prototype.options_={children:["seekBar"]},pt.registerComponent("ProgressControl",Ft);jt=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,["enterpictureinpicture","leavepictureinpicture"],function(e){return i.handlePictureInPictureChange(e)}),i.on(e,["disablepictureinpicturechanged","loadedmetadata"],function(e){return i.handlePictureInPictureEnabledChange(e)}),i.disable(),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-picture-in-picture-control "+n.prototype.buildCSSClass.call(this)},t.handlePictureInPictureEnabledChange=function(){document.pictureInPictureEnabled&&!1===this.player_.disablePictureInPicture()?this.enable():this.disable()},t.handlePictureInPictureChange=function(e){this.player_.isInPictureInPicture()?this.controlText("Exit Picture-in-Picture"):this.controlText("Picture-in-Picture"),this.handlePictureInPictureEnabledChange()},t.handleClick=function(e){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()},e}(sn);jt.prototype.controlText_="Picture-in-Picture",pt.registerComponent("PictureInPictureToggle",jt);j=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"fullscreenchange",function(e){return i.handleFullscreenChange(e)}),!1===document[e.fsApi_.fullscreenEnabled]&&i.disable(),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-fullscreen-control "+n.prototype.buildCSSClass.call(this)},t.handleFullscreenChange=function(e){this.player_.isFullscreen()?this.controlText("Non-Fullscreen"):this.controlText("Fullscreen")},t.handleClick=function(e){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()},e}(sn);j.prototype.controlText_="Fullscreen",pt.registerComponent("FullscreenToggle",j);pt.registerComponent("VolumeLevel",function(t){function e(){return t.apply(this,arguments)||this}return mt(e,t),e.prototype.createEl=function(){var e=t.prototype.createEl.call(this,"div",{className:"vjs-volume-level"});return e.appendChild(t.prototype.createEl.call(this,"span",{className:"vjs-control-text"})),e},e}(pt)),pt.registerComponent("VolumeLevelTooltip",function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=We(Ve(ft(t),t.update),30),t}mt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-volume-tooltip"},{"aria-hidden":"true"})},t.update=function(e,t,i,n){if(!i){var r=de(this.el_),a=de(this.player_.el()),i=e.width*t;if(!a||!r)return;t=e.left-a.left+i,a=e.width-i+(a.right-e.right),e=r.width/2;t<e?e+=e-t:a<e&&(e=a),e<0?e=0:e>r.width&&(e=r.width),this.el_.style.right="-"+e+"px"}this.write(n+"%")},t.write=function(e){J(this.el_,e)},t.updateVolume=function(e,t,i,n,r){var a=this;this.requestNamedAnimationFrame("VolumeLevelTooltip#updateVolume",function(){a.update(e,t,i,n.toFixed(0)),r&&r()})},e}(pt));k=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=We(Ve(ft(t),t.update),30),t}
4715mt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t,i){var n=this,r=100*t;this.getChild("volumeLevelTooltip").updateVolume(e,t,i,r,function(){i?n.el_.style.bottom=e.height*t+"px":n.el_.style.left=e.width*t+"px"})},e}(pt);k.prototype.options_={children:["volumeLevelTooltip"]},pt.registerComponent("MouseVolumeLevelDisplay",k);f=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on("slideractive",function(e){return i.updateLastVolume_(e)}),i.on(e,"volumechange",function(e){return i.updateARIAAttributes(e)}),e.ready(function(){return i.updateARIAAttributes()}),i}mt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})},t.handleMouseDown=function(e){_e(e)&&n.prototype.handleMouseDown.call(this,e)},t.handleMouseMove=function(e){var t,i,n,r=this.getChild("mouseVolumeLevelDisplay");r&&(t=de(n=this.el()),i=this.vertical(),n=pe(n,e),n=i?n.y:n.x,n=cn(n,0,1),r.update(t,n,i)),_e(e)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(e)))},t.checkMuted=function(){this.player_.muted()&&this.player_.muted(!1)},t.getPercent=function(){return this.player_.muted()?0:this.player_.volume()},t.stepForward=function(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)},t.stepBack=function(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)},t.updateARIAAttributes=function(e){var t=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",t),this.el_.setAttribute("aria-valuetext",t+"%")},t.volumeAsPercentage_=function(){return Math.round(100*this.player_.volume())},t.updateLastVolume_=function(){var e=this,t=this.player_.volume();this.one("sliderinactive",function(){0===e.player_.volume()&&e.player_.lastVolume_(t)})},e}(li);f.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},q||A||f.prototype.options_.children.splice(0,0,"mouseVolumeLevelDisplay"),f.prototype.playerEvent="volumechange",pt.registerComponent("VolumeBar",f);ui=function(a){function e(e,t){var i,n,r;return(t=void 0===t?{}:t).vertical=t.vertical||!1,"undefined"!=typeof t.volumeBar&&!S(t.volumeBar)||(t.volumeBar=t.volumeBar||{},t.volumeBar.vertical=t.vertical),i=a.call(this,e,t)||this,n=ft(i),(r=e).tech_&&!r.tech_.featuresVolumeControl&&n.addClass("vjs-hidden"),n.on(r,"loadstart",function(){r.tech_.featuresVolumeControl?n.removeClass("vjs-hidden"):n.addClass("vjs-hidden")}),i.throttledHandleMouseMove=We(Ve(ft(i),i.handleMouseMove),30),i.handleMouseUpHandler_=function(e){return i.handleMouseUp(e)},i.on("mousedown",function(e){return i.handleMouseDown(e)}),i.on("touchstart",function(e){return i.handleMouseDown(e)}),i.on("mousemove",function(e){return i.handleMouseMove(e)}),i.on(i.volumeBar,["focus","slideractive"],function(){i.volumeBar.addClass("vjs-slider-active"),i.addClass("vjs-slider-active"),i.trigger("slideractive")}),i.on(i.volumeBar,["blur","sliderinactive"],function(){i.volumeBar.removeClass("vjs-slider-active"),i.removeClass("vjs-slider-active"),i.trigger("sliderinactive")}),i}mt(e,a);var t=e.prototype;return t.createEl=function(){var e="vjs-volume-horizontal";return this.options_.vertical&&(e="vjs-volume-vertical"),a.prototype.createEl.call(this,"div",{className:"vjs-volume-control vjs-control "+e})},t.handleMouseDown=function(e){var t=this.el_.ownerDocument;this.on(t,"mousemove",this.throttledHandleMouseMove),this.on(t,"touchmove",this.throttledHandleMouseMove),this.on(t,"mouseup",this.handleMouseUpHandler_),this.on(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument;this.off(t,"mousemove",this.throttledHandleMouseMove),this.off(t,"touchmove",this.throttledHandleMouseMove),this.off(t,"mouseup",this.handleMouseUpHandler_),this.off(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseMove=function(e){this.volumeBar.handleMouseMove(e)},e}(pt);ui.prototype.options_={children:["volumeBar"]}
4715,pt.registerComponent("VolumeControl",ui);Xt=function(a){function e(e,t){var i,n,r=a.call(this,e,t)||this;return i=ft(r),(n=e).tech_&&!n.tech_.featuresMuteControl&&i.addClass("vjs-hidden"),i.on(n,"loadstart",function(){n.tech_.featuresMuteControl?i.removeClass("vjs-hidden"):i.addClass("vjs-hidden")}),r.on(e,["loadstart","volumechange"],function(e){return r.update(e)}),r}mt(e,a);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-mute-control "+a.prototype.buildCSSClass.call(this)},t.handleClick=function(e){var t=this.player_.volume(),i=this.player_.lastVolume_();0===t?(this.player_.volume(i<.1?.1:i),this.player_.muted(!1)):this.player_.muted(!this.player_.muted())},t.update=function(e){this.updateIcon_(),this.updateControlText_()},t.updateIcon_=function(){var e=this.player_.volume(),t=3;q&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===e||this.player_.muted()?t=0:e<.33?t=1:e<.67&&(t=2);for(var i=0;i<4;i++)ie(this.el_,"vjs-vol-"+i);te(this.el_,"vjs-vol-"+t)},t.updateControlText_=function(){var e=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==e&&this.controlText(e)},e}(sn);Xt.prototype.controlText_="Mute",pt.registerComponent("MuteToggle",Xt);I=function(n){function e(e,t){var i;return"undefined"!=typeof(t=void 0===t?{}:t).inline?t.inline=t.inline:t.inline=!0,"undefined"!=typeof t.volumeControl&&!S(t.volumeControl)||(t.volumeControl=t.volumeControl||{},t.volumeControl.vertical=!t.inline),(i=n.call(this,e,t)||this).handleKeyPressHandler_=function(e){return i.handleKeyPress(e)},i.on(e,["loadstart"],function(e){return i.volumePanelState_(e)}),i.on(i.muteToggle,"keyup",function(e){return i.handleKeyPress(e)}),i.on(i.volumeControl,"keyup",function(e){return i.handleVolumeControlKeyUp(e)}),i.on("keydown",function(e){return i.handleKeyPress(e)}),i.on("mouseover",function(e){return i.handleMouseOver(e)}),i.on("mouseout",function(e){return i.handleMouseOut(e)}),i.on(i.volumeControl,["slideractive"],i.sliderActive_),i.on(i.volumeControl,["sliderinactive"],i.sliderInactive_),i}mt(e,n);var t=e.prototype;return t.sliderActive_=function(){this.addClass("vjs-slider-active")},t.sliderInactive_=function(){this.removeClass("vjs-slider-active")},t.volumePanelState_=function(){this.volumeControl.hasClass("vjs-hidden")&&this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-hidden"),this.volumeControl.hasClass("vjs-hidden")&&!this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-mute-toggle-only")},t.createEl=function(){var e="vjs-volume-panel-horizontal";return this.options_.inline||(e="vjs-volume-panel-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-panel vjs-control "+e})},t.dispose=function(){this.handleMouseOut(),n.prototype.dispose.call(this)},t.handleVolumeControlKeyUp=function(e){ht.isEventKey(e,"Esc")&&this.muteToggle.focus()},t.handleMouseOver=function(e){this.addClass("vjs-hover"),Be(document,"keyup",this.handleKeyPressHandler_)},t.handleMouseOut=function(e){this.removeClass("vjs-hover"),Fe(document,"keyup",this.handleKeyPressHandler_)},t.handleKeyPress=function(e){ht.isEventKey(e,"Esc")&&this.handleMouseOut()},e}(pt);I.prototype.options_={children:["muteToggle","volumeControl"]},pt.registerComponent("VolumePanel",I);var hn=function(n){function e(e,t){var i=n.call(this,e,t)||this;return t&&(i.menuButton_=t.menuButton),i.focusedChild_=-1,i.on("keydown",function(e){return i.handleKeyDown(e)}),i.boundHandleBlur_=function(e){return i.handleBlur(e)},i.boundHandleTapClick_=function(e){return i.handleTapClick(e)},i}mt(e,n);var t=e.prototype;return t.addEventListenerForItem=function(e){e instanceof pt&&(this.on(e,"blur",this.boundHandleBlur_),this.on(e,["tap","click"],this.boundHandleTapClick_))},t.removeEventListenerForItem=function(e){e instanceof pt&&(this.off(e,"blur",this.boundHandleBlur_),this.off(e,["tap","click"],this.boundHandleTapClick_))},t.removeChild=function(e){"string"==typeof e&&(e=this.getChild(e)),this.removeEventListenerForItem(e),n.prototype.removeChild.call(this,e)},t.addItem=function(e){e=this.addChild(e);e&&this.addEventListenerForItem(e)},t.createEl=function(){var e=this.options_.contentElType||"ul";this.contentEl_=$(e,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");e=n.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return e.appendChild(this.contentEl_),Be(e,"click",function(e){e.preventDefault(),e.stopImmediatePropagation()}),e},t.dispose=function(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,n.prototype.dispose.call(this)},t.handleBlur=function(e){var t=e.relatedTarget||document.activeElement;this.children().some(function(e){return e.el()===t})||(e=this.menuButton_)&&e.buttonPressed_&&t!==e.el().firstChild&&e.unpressButton()},t.handleTapClick=function(t){var e;this.menuButton_&&(this.menuButton_.unpressButton(),e=this.children(),!Array.isArray(e)||(e=e.filter(function(e){return e.el()===t.target})[0])&&"CaptionSettingsMenuItem"!==e.name()&&this.menuButton_.focus())},t.handleKeyDown=function(e){ht.isEventKey(e,"Left")||ht.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):(ht.isEventKey(e,"Right")||ht.isEventKey(e,"Up"))&&(e.preventDefault(),e.stopPropagation(),this.stepBack())},t.stepForward=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_+1),this.focus(e)},t.stepBack=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_-1),this.focus(e)},t.focus=function(e){void 0===e&&(e=0);var t=this.children().slice();t.length&&t[0].hasClass("vjs-menu-title")&&t.shift(),0<t.length&&(e<0?e=0:e>=t.length&&(e=t.length-1),t[this.focusedChild_=e].el_.focus())},e}(pt);pt.registerComponent("Menu",hn);Bt=function(n){function e(e,t){var i;(i=n.call(this,e,t=void 0===t?{}:t)||this).menuButton_=new sn(e,t),i.menuButton_.controlText(i.controlText_),i.menuButton_.el_.setAttribute("aria-haspopup","true");t=sn.prototype.buildCSSClass();i.menuButton_.el_.className=i.buildCSSClass()+" "+t,i.menuButton_.removeClass("vjs-control"),i.addChild(i.menuButton_),i.update(),i.enabled_=!0;t=function(e){return i.handleClick(e)};return i.handleMenuKeyUp_=function(e){return i.handleMenuKeyUp(e)},i.on(i.menuButton_,"tap",t),i.on(i.menuButton_,"click",t),i.on(i.menuButton_,"keydown",function(e){return i.handleKeyDown(e)}),i.on(i.menuButton_,"mouseenter",function(){i.addClass("vjs-hover"),i.menu.show(),Be(document,"keyup",i.handleMenuKeyUp_)}
4715),i.on("mouseleave",function(e){return i.handleMouseLeave(e)}),i.on("keydown",function(e){return i.handleSubmenuKeyDown(e)}),i}mt(e,n);var t=e.prototype;return t.update=function(){var e=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=e,this.addChild(e),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?this.hide():this.show()},t.createMenu=function(){var e,t=new hn(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title&&(e=$("li",{className:"vjs-menu-title",textContent:ut(this.options_.title),tabIndex:-1}),e=new pt(this.player_,{el:e}),t.addItem(e)),this.items=this.createItems(),this.items)for(var i=0;i<this.items.length;i++)t.addItem(this.items[i]);return t},t.createItems=function(){},t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildWrapperCSSClass()},{})},t.buildWrapperCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+sn.prototype.buildCSSClass()+" "+n.prototype.buildCSSClass.call(this)},t.buildCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+n.prototype.buildCSSClass.call(this)},t.controlText=function(e,t){return void 0===t&&(t=this.menuButton_.el()),this.menuButton_.controlText(e,t)},t.dispose=function(){this.handleMouseLeave(),n.prototype.dispose.call(this)},t.handleClick=function(e){this.buttonPressed_?this.unpressButton():this.pressButton()},t.handleMouseLeave=function(e){this.removeClass("vjs-hover"),Fe(document,"keyup",this.handleMenuKeyUp_)},t.focus=function(){this.menuButton_.focus()},t.blur=function(){this.menuButton_.blur()},t.handleKeyDown=function(e){ht.isEventKey(e,"Esc")||ht.isEventKey(e,"Tab")?(this.buttonPressed_&&this.unpressButton(),ht.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus())):(ht.isEventKey(e,"Up")||ht.isEventKey(e,"Down"))&&(this.buttonPressed_||(e.preventDefault(),this.pressButton()))},t.handleMenuKeyUp=function(e){(ht.isEventKey(e,"Esc")||ht.isEventKey(e,"Tab"))&&this.removeClass("vjs-hover")},t.handleSubmenuKeyPress=function(e){this.handleSubmenuKeyDown(e)},t.handleSubmenuKeyDown=function(e){(ht.isEventKey(e,"Esc")||ht.isEventKey(e,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),ht.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus()))},t.pressButton=function(){this.enabled_&&(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),q&&Y()||this.menu.focus())},t.unpressButton=function(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))},t.disable=function(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()},t.enable=function(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()},e}(pt);pt.registerComponent("MenuButton",Bt);Ft=function(r){function e(e,t){var i=t.tracks,t=r.call(this,e,t)||this;if(t.items.length<=1&&t.hide(),!i)return ft(t);var n=Ve(ft(t),t.update);return i.addEventListener("removetrack",n),i.addEventListener("addtrack",n),i.addEventListener("labelchange",n),t.player_.on("ready",n),t.player_.on("dispose",function(){i.removeEventListener("removetrack",n),i.removeEventListener("addtrack",n),i.removeEventListener("labelchange",n)}),t}return mt(e,r),e}(Bt);pt.registerComponent("TrackButton",Ft);var pn=["Tab","Esc","Up","Down","Right","Left"],jt=function(n){function e(e,t){e=n.call(this,e,t)||this;return e.selectable=t.selectable,e.isSelected_=t.selected||!1,e.multiSelectable=t.multiSelectable,e.selected(e.isSelected_),e.selectable?e.multiSelectable?e.el_.setAttribute("role","menuitemcheckbox"):e.el_.setAttribute("role","menuitemradio"):e.el_.setAttribute("role","menuitem"),e}mt(e,n);var t=e.prototype;return t.createEl=function(e,t,i){this.nonIconControl=!0;i=n.prototype.createEl.call(this,"li",b({className:"vjs-menu-item",tabIndex:-1},t),i);return i.replaceChild($("span",{className:"vjs-menu-item-text",textContent:this.localize(this.options_.label)}),i.querySelector(".vjs-icon-placeholder")),i},t.handleKeyDown=function(t){pn.some(function(e){return ht.isEventKey(t,e)})||n.prototype.handleKeyDown.call(this,t)},t.handleClick=function(e){this.selected(!0)},t.selected=function(e){this.selectable&&(e?(this.addClass("vjs-selected"),this.el_.setAttribute("aria-checked","true"),this.controlText(", selected"),this.isSelected_=!0):(this.removeClass("vjs-selected"),this.el_.setAttribute("aria-checked","fal
4715se"),this.controlText(""),this.isSelected_=!1))},e}(C);pt.registerComponent("MenuItem",jt);var fn=function(u){function e(e,t){var n,i=t.track,r=e.textTracks();t.label=i.label||i.language||"Unknown",t.selected="showing"===i.mode,(n=u.call(this,e,t)||this).track=i,n.kinds=(t.kinds||[t.kind||n.track.kind]).filter(Boolean);function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(ft(n),t)}function s(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleSelectedLanguageChange.apply(ft(n),t)}var o;return e.on(["loadstart","texttrackchange"],a),r.addEventListener("change",a),r.addEventListener("selectedlanguagechange",s),n.on("dispose",function(){e.off(["loadstart","texttrackchange"],a),r.removeEventListener("change",a),r.removeEventListener("selectedlanguagechange",s)}),void 0===r.onchange&&n.on(["tap","click"],function(){if("object"!=typeof window.Event)try{o=new window.Event("change")}catch(e){}o||(o=document.createEvent("Event")).initEvent("change",!0,!0),r.dispatchEvent(o)}),n.handleTracksChange(),n}mt(e,u);var t=e.prototype;return t.handleClick=function(e){var t=this.track,i=this.player_.textTracks();if(u.prototype.handleClick.call(this,e),i)for(var n=0;n<i.length;n++){var r=i[n];-1!==this.kinds.indexOf(r.kind)&&(r===t?"showing"!==r.mode&&(r.mode="showing"):"disabled"!==r.mode&&(r.mode="disabled"))}},t.handleTracksChange=function(e){var t="showing"===this.track.mode;t!==this.isSelected_&&this.selected(t)},t.handleSelectedLanguageChange=function(e){var t;"showing"===this.track.mode&&((t=this.player_.cache_.selectedLanguage)&&t.enabled&&t.language===this.track.language&&t.kind!==this.track.kind||(this.player_.cache_.selectedLanguage={enabled:!0,language:this.track.language,kind:this.track.kind}))},t.dispose=function(){this.track=null,u.prototype.dispose.call(this)},e}(jt);pt.registerComponent("TextTrackMenuItem",fn);var mn=function(i){function e(e,t){return t.track={player:e,kind:t.kind,kinds:t.kinds,default:!1,mode:"disabled"},t.kinds||(t.kinds=[t.kind]),t.label?t.track.label=t.label:t.track.label=t.kinds.join(" and ")+" off",t.selectable=!0,t.multiSelectable=!1,i.call(this,e,t)||this}mt(e,i);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<this.options_.kinds.indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i!==this.isSelected_&&this.selected(i)},t.handleSelectedLanguageChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<["captions","descriptions","subtitles"].indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i&&(this.player_.cache_.selectedLanguage={enabled:!1})},e}(fn);pt.registerComponent("OffTextTrackMenuItem",mn);j=function(i){function e(e,t){return(t=void 0===t?{}:t).tracks=e.textTracks(),i.call(this,e,t)||this}return mt(e,i),e.prototype.createItems=function(e,t){var i;void 0===t&&(t=fn),this.label_&&(i=this.label_+" off"),(e=void 0===e?[]:e).push(new mn(this.player_,{kinds:this.kinds_,kind:this.kind_,label:i})),this.hideThreshold_+=1;var n=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(var r=0;r<n.length;r++){var a,s=n[r];-1<this.kinds_.indexOf(s.kind)&&((a=new t(this.player_,{track:s,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1})).addClass("vjs-"+s.kind+"-menu-item"),e.push(a))}return e},e}(Ft);pt.registerComponent("TextTrackButton",j);var gn=function(a){function e(e,t){var i=t.track,n=t.cue,r=e.currentTime();return t.selectable=!0,t.multiSelectable=!1,t.label=n.text,t.selected=n.startTime<=r&&r<n.endTime,(t=a.call(this,e,t)||this).track=i,t.cue=n,i.addEventListener("cuechange",Ve(ft(t),t.update)),t}mt(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player_.currentTime(this.cue.startTime),this.update(this.cue.startTime)},t.update=function(e){var t=this.cue,i=this.player_.currentTime();this.selected(t.startTime<=i&&i<t.endTime)},e}(jt);pt.registerComponent("ChaptersTrackMenuItem",gn);k=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildWrapperCSSClass.call(this)},t.update=function(e){this.track_&&(!e||"addtrack"!==e.type&&"removetrack"!==e.type)||this.setTrack(this.findChapter
4715sTrack()),n.prototype.update.call(this)},t.setTrack=function(e){var t;this.track_!==e&&(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_&&((t=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_))&&t.removeEventListener("load",this.updateHandler_),this.track_=null),this.track_=e,this.track_&&(this.track_.mode="hidden",(e=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_))&&e.addEventListener("load",this.updateHandler_)))},t.findChaptersTrack=function(){for(var e=this.player_.textTracks()||[],t=e.length-1;0<=t;t--){var i=e[t];if(i.kind===this.kind_)return i}},t.getMenuCaption=function(){return this.track_&&this.track_.label?this.track_.label:this.localize(ut(this.kind_))},t.createMenu=function(){return this.options_.title=this.getMenuCaption(),n.prototype.createMenu.call(this)},t.createItems=function(){var e=[];if(!this.track_)return e;var t=this.track_.cues;if(!t)return e;for(var i=0,n=t.length;i<n;i++){var r=t[i],r=new gn(this.player_,{track:this.track_,cue:r});e.push(r)}return e},e}(j);k.prototype.kind_="chapters",k.prototype.controlText_="Chapters",pt.registerComponent("ChaptersButton",k);li=function(a){function e(e,t,i){var i=a.call(this,e,t,i)||this,n=e.textTracks(),r=Ve(ft(i),i.handleTracksChange);return n.addEventListener("change",r),i.on("dispose",function(){n.removeEventListener("change",r)}),i}mt(e,a);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!1,n=0,r=t.length;n<r;n++){var a=t[n];if(a.kind!==this.kind_&&"showing"===a.mode){i=!0;break}}i?this.disable():this.enable()},t.buildCSSClass=function(){return"vjs-descriptions-button "+a.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-descriptions-button "+a.prototype.buildWrapperCSSClass.call(this)},e}(j);li.prototype.kind_="descriptions",li.prototype.controlText_="Descriptions",pt.registerComponent("DescriptionsButton",li);f=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildWrapperCSSClass.call(this)},e}(j);f.prototype.kind_="subtitles",f.prototype.controlText_="Subtitles",pt.registerComponent("SubtitlesButton",f);var yn=function(i){function e(e,t){return t.track={player:e,kind:t.kind,label:t.kind+" settings",selectable:!1,default:!1,mode:"disabled"},t.selectable=!1,t.name="CaptionSettingsMenuItem",(e=i.call(this,e,t)||this).addClass("vjs-texttrack-settings"),e.controlText(", opens "+t.kind+" settings dialog"),e}return mt(e,i),e.prototype.handleClick=function(e){this.player().getChild("textTrackSettings").open()},e}(fn);pt.registerComponent("CaptionSettingsMenuItem",yn);ui=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-captions-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-captions-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new yn(this.player_,{kind:this.kind_})),this.hideThreshold_+=1),n.prototype.createItems.call(this,e)},e}(j);ui.prototype.kind_="captions",ui.prototype.controlText_="Captions",pt.registerComponent("CaptionsButton",ui);var vn=function(n){function e(){return n.apply(this,arguments)||this}return mt(e,n),e.prototype.createEl=function(e,t,i){t=n.prototype.createEl.call(this,e,t,i),i=t.querySelector(".vjs-menu-item-text");return"captions"===this.options_.track.kind&&(i.appendChild($("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),i.appendChild($("span",{className:"vjs-control-text",textContent:" "+this.localize("Captions")}))),t},e}(fn);pt.registerComponent("SubsCapsMenuItem",vn);Xt=function(i){function e(e,t){return(t=i.call(this,e,t=void 0===t?{}:t)||this).label_="subtitles",-1<["en","en-us","en-ca","fr-ca"].indexOf(t.player_.language_)&&(t.label_="captions"),t.menuButton_.controlText(ut(t.label_)),t}
4715mt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subs-caps-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subs-caps-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new yn(this.player_,{kind:this.label_})),this.hideThreshold_+=1),e=i.prototype.createItems.call(this,e,vn)},e}(j);Xt.prototype.kinds_=["captions","subtitles"],Xt.prototype.controlText_="Subtitles",pt.registerComponent("SubsCapsButton",Xt);var _n=function(s){function e(e,t){var n,i=t.track,r=e.audioTracks();t.label=i.label||i.language||"Unknown",t.selected=i.enabled,(n=s.call(this,e,t)||this).track=i,n.addClass("vjs-"+i.kind+"-menu-item");function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(ft(n),t)}return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}mt(e,s);var t=e.prototype;return t.createEl=function(e,t,i){t=s.prototype.createEl.call(this,e,t,i),i=t.querySelector(".vjs-menu-item-text");return"main-desc"===this.options_.track.kind&&(i.appendChild($("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),i.appendChild($("span",{className:"vjs-control-text",textContent:" "+this.localize("Descriptions")}))),t},t.handleClick=function(e){if(s.prototype.handleClick.call(this,e),this.track.enabled=!0,this.player_.tech_.featuresNativeAudioTracks)for(var t=this.player_.audioTracks(),i=0;i<t.length;i++){var n=t[i];n!==this.track&&(n.enabled=n===this.track)}},t.handleTracksChange=function(e){this.selected(this.track.enabled)},e}(jt);pt.registerComponent("AudioTrackMenuItem",_n);I=function(i){function e(e,t){return(t=void 0===t?{}:t).tracks=e.audioTracks(),i.call(this,e,t)||this}mt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-audio-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-audio-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(e){void 0===e&&(e=[]),this.hideThreshold_=1;for(var t=this.player_.audioTracks(),i=0;i<t.length;i++){var n=t[i];e.push(new _n(this.player_,{track:n,selectable:!0,multiSelectable:!1}))}return e},e}(Ft);I.prototype.controlText_="Audio Track",pt.registerComponent("AudioTrackButton",I);var bn=function(a){function e(e,t){var i,n=t.rate,r=parseFloat(n,10);return t.label=n,t.selected=r===e.playbackRate(),t.selectable=!0,t.multiSelectable=!1,(i=a.call(this,e,t)||this).label=n,i.rate=r,i.on(e,"ratechange",function(e){return i.update(e)}),i}mt(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player().playbackRate(this.rate)},t.update=function(e){this.selected(this.player().playbackRate()===this.rate)},e}(jt);bn.prototype.contentElType="button",pt.registerComponent("PlaybackRateMenuItem",bn);C=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.menuButton_.el_.setAttribute("aria-describedby",i.labelElId_),i.updateVisibility(),i.updateLabel(),i.on(e,"loadstart",function(e){return i.updateVisibility(e)}),i.on(e,"ratechange",function(e){return i.updateLabel(e)}),i.on(e,"playbackrateschange",function(e){return i.handlePlaybackRateschange(e)}),i}mt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this);return this.labelElId_="vjs-playback-rate-value-label-"+this.id_,this.labelEl_=$("div",{className:"vjs-playback-rate-value",id:this.labelElId_,textContent:"1x"}),e.appendChild(this.labelEl_),e},t.dispose=function(){this.labelEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){for(var e=this.playbackRates(),t=[],i=e.length-1;0<=i;i--)t.push(new bn(this.player(),{rate:e[i]+"x"}));return t},t.updateARIAAttributes=function(){this.el().setAttribute("aria-valuenow",this.player().playbackRate())},t.handleClick=function(e){var t=this.player().playbackRate(),i=this.playbackRates(),t=(i.indexOf(t)+1)%i.length;this.player().playbackRate(i[t])},t.handlePlaybackRateschange=function(e){this.update()},t.playbackRates=function(){var e=this.player();return e.playbackRates&&e.playbackRates()||[]},t.playbackRateSupported=function(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&0<this.playbackRates().length},t.updateVisibility=function(e){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")},t.updateLabel=function(e){this.playbackRateSupported()&&(this.labelEl_.textContent=this.player().playbackRate()+"x")},e}(Bt);C.prototype.controlText_="Playback Rate",pt.registerComponent("PlaybackRateMenuButton",C);k=function(n){function e(){return n.apply(this,arguments)||this}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-spacer "+n.prototype.buildCSSClass.call(this)},t.createEl=function(e,t,i){return void 0===e&&(e="div"),void 0===i&&(i={}),(t=void 0===t?{}:t).className||(t.className=this.buildCSSClass()),n.prototype.createEl.call(this,e,t,i)},e}(pt);pt.registerComponent("Spacer",k),pt.registerComponent("CustomControlSpacer",function(e){function t(){return e.apply(this,arguments)||this}mt(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-custom-control-spacer "+e.prototype.buildCSSClass.call(this)},i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),textContent:" "})},t}(k));li=function(e){function t(){return e.apply(this,arguments)||this}return mt(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-control-bar",dir:"ltr"})},t}(pt);li.prototype.options_={children:["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","fullscreenToggle"]},"exitPictureInPicture"in document&&li.prototype.options_.children.splice(li.prototype.options_.children.length-1,0,"pictureInPictureToggle"),pt.registerComponent("ControlBar",li);f=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"error",function(e){return i.open(e)}),i}mt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-error-display "+n.prototype.buildCSSClass.call(this)},t.content=function(){var e=this.player().error();return e?this.localize(e.message):""},e}(At);f.prototype.options_=g({}
vendor: 7,115 bytes, line 4715
4715,At.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),pt.registerComponent("ErrorDisplay",f);var Tn="vjs-text-track-settings",ui=["#000","Black"],j=["#00F","Blue"],Xt=["#0FF","Cyan"],Ft=["#0F0","Green"],I=["#F0F","Magenta"],jt=["#F00","Red"],Bt=["#FFF","White"],C=["#FF0","Yellow"],k=["1","Opaque"],li=["0.5","Semi-Transparent"],f=["0","Transparent"],Sn={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[ui,Bt,jt,Ft,j,C,I,Xt]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Transparency",options:[k,li,f]},color:{selector:".vjs-fg-color > select",id:"captions-foreground-color-%s",label:"Color",options:[Bt,ui,jt,Ft,j,C,I,Xt]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Dropshadow"]]},fontFamily:{selector:".vjs-font-family > select",id:"captions-font-family-%s",label:"Font Family",options:[["proportionalSansSerif","Proportional Sans-Serif"],["monospaceSansSerif","Monospace Sans-Serif"],["proportionalSerif","Proportional Serif"],["monospaceSerif","Monospace Serif"],["casual","Casual"],["script","Script"],["small-caps","Small Caps"]]},fontPercent:{selector:".vjs-font-percent > select",id:"captions-font-size-%s",label:"Font Size",options:[["0.50","50%"],["0.75","75%"],["1.00","100%"],["1.25","125%"],["1.50","150%"],["1.75","175%"],["2.00","200%"],["3.00","300%"],["4.00","400%"]],default:2,parser:function(e){return"1.00"===e?null:Number(e)}},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Transparency",options:[k,li]},windowColor:{selector:".vjs-window-color > select",id:"captions-window-color-%s",label:"Color"},windowOpacity:{selector:".vjs-window-opacity > select",id:"captions-window-opacity-%s",label:"Transparency",options:[f,li,k]}};function wn(e,t){if((e=t?t(e):e)&&"none"!==e)return e}Sn.windowColor.options=Sn.backgroundColor.options,pt.registerComponent("TextTrackSettings",function(n){function e(e,t){var i;return t.temporary=!1,(i=n.call(this,e,t)||this).updateDisplay=i.updateDisplay.bind(ft(i)),i.fill(),i.hasBeenOpened_=i.hasBeenFilled_=!0,i.endDialog=$("p",{className:"vjs-control-text",textContent:i.localize("End of dialog window.")}),i.el().appendChild(i.endDialog),i.setDefaults(),void 0===t.persistTextTrackSettings&&(i.options_.persistTextTrackSettings=i.options_.playerOptions.persistTextTrackSettings),i.on(i.$(".vjs-done-button"),"click",function(){i.saveSettings(),i.close()}),i.on(i.$(".vjs-default-button"),"click",function(){i.setDefaults(),i.updateDisplay()}),_(Sn,function(e){i.on(i.$(e.selector),"change",i.updateDisplay)}),i.options_.persistTextTrackSettings&&i.restoreSettings(),i}mt(e,n);var t=e.prototype;return t.dispose=function(){this.endDialog=null,n.prototype.dispose.call(this)},t.createElSelect_=function(e,t,i){var n=this;void 0===t&&(t=""),void 0===i&&(i="label");var e=Sn[e],r=e.id.replace("%s",this.id_),a=[t,r].join(" ").trim();return["<"+i+' id="'+r+'" class="'+("label"===i?"vjs-label":"")+'">',this.localize(e.label),"</"+i+">",'<select aria-labelledby="'+a+'">'].concat(e.options.map(function(e){var t=r+"-"+e[1].replace(/\W+/g,"");return['<option id="'+t+'" value="'+e[0]+'" ','aria-labelledby="'+a+" "+t+'">',n.localize(e[1]),"</option>"].join("")})).concat("</select>").join("")},t.createElFgColor_=function(){var e="captions-text-legend-"+this.id_;return['<fieldset class="vjs-fg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Text"),"</legend>",this.createElSelect_("color",e),'<span class="vjs-text-opacity vjs-opacity">',this.createElSelect_("textOpacity",e),"</span>","</fieldset>"].join("")},t.createElBgColor_=function(){var e="captions-background-"+this.id_;return['<fieldset class="vjs-bg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Background"),"</legend>",this.createElSelect_("backgroundColor",e),'<span class="vjs-bg-opacity vjs-opacity">',this.createElSelect_("backgroundOpacity",e),"</span>","</fieldset>"].join("")},t.createElWinColor_=function(){var e="captions-window-"+this.id_;return['<fieldset class="vjs-window-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Window"),"</legend>",this.createElSelect_("windowColor",e),'<span class="vjs-window-opacity vjs-opacity">',this.createElSelect_("windowOpacity",e),"</span>","</fieldset>"].join("")},t.createElColors_=function(){return $("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})},t.createElFont_=function(){return $("div",{className:"vjs-track-settings-font",innerHTML:['<fieldset class="vjs-font-percent vjs-track-setting">',this.createElSelect_("fontPercent","","legend"),"</fieldset>",'<fieldset class="vjs-edge-style vjs-track-setting">',this.createElSelect_("edgeStyle","","legend"),"</fieldset>",'<fieldset class="vjs-font-family vjs-track-setting">',this.createElSelect_("fontFamily","","legend"),"</fieldset>"].join("")})},t.createElControls_=function(){var e=this.localize("restore all settings to the default values");return $("div",{className:"vjs-track-settings-controls",innerHTML:['<button type="button" class="vjs-default-button" title="'+e+'">',this.localize("Reset"),'<span class="vjs-control-text"> '+e+"</span>","</button>",'<button type="button" class="vjs-done-button">'+this.localize("Done")+"</button>"].join("")})},t.content=function(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]},t.label=function(){return this.localize("Caption Settings Dialog")},t.description=function(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")},t.buildCSSClass=function(){return n.prototype.buildCSSClass.call(this)+" vjs-text-track-settings"},t.getValues=function(){var i,n,e,r=this;return n=function(e,t,i){var n,t=(n=r.$(t.selector),t=t.parser,wn(n.options[n.options.selectedIndex].value,t));return void 0!==t&&(e[i]=t),e},void 0===(e={})&&(e=0),v(i=Sn).reduce(function(e,t){return n(e,i[t],t)},e)},t.setValues=function(i){var n=this;_(Sn,function(e,t){!function(e,t,i){if(t)for(var n=0;n<e.options.length;n++)if(wn(e.options[n].value,i)===t){e.selectedIndex=n;break}}(n.$(e.selector),i[t],e.parser)})},t.setDefaults=function(){var i=this;_(Sn,function(e){var t=e.hasOwnProperty("default")?e.default:0;i.$(e.selector).selectedIndex=t})},t.restoreSettings=function(){var e;try{e=JSON.parse(window.localStorage.getItem(Tn))}catch(e){h.warn(e)}e&&this.setValues(e)},t.saveSettings=function(){if(this.options_.persistTextTrackSettings){var e=this.getValues();try{Object.keys(e).length?window.localStorage.setItem(Tn,JSON.stringify(e)):window.localStorage.removeItem(Tn)}catch(e){h.warn(e)}}},t.updateDisplay=function(){var e=this.player_.getChild("textTrackDisplay");e&&e.updateDisplay()},t.conditionalBlur_=function(){this.previouslyActiveEl_=null;var e=this.player_.controlBar,t=e&&e.subsCapsButton,e=e&&e.captionsButton;
4715t?t.focus():e&&e.focus()},e}(At)),pt.registerComponent("ResizeManager",function(a){function e(e,t){var i,n=t.ResizeObserver||window.ResizeObserver,r=lt({createEl:!(n=null===t.ResizeObserver?!1:n),reportTouchActivity:!1},t);return(i=a.call(this,e,r)||this).ResizeObserver=t.ResizeObserver||window.ResizeObserver,i.loadListener_=null,i.resizeObserver_=null,i.debouncedHandler_=Ge(function(){i.resizeHandler()},100,!1,ft(i)),n?(i.resizeObserver_=new i.ResizeObserver(i.debouncedHandler_),i.resizeObserver_.observe(e.el())):(i.loadListener_=function(){var e,t;i.el_&&i.el_.contentWindow&&(e=i.debouncedHandler_,t=i.unloadListener_=function(){Fe(this,"resize",e),Fe(this,"unload",t),t=null},Be(i.el_.contentWindow,"unload",t),Be(i.el_.contentWindow,"resize",e))},i.one("load",i.loadListener_)),i}mt(e,a);var t=e.prototype;return t.createEl=function(){return a.prototype.createEl.call(this,"iframe",{className:"vjs-resize-manager",tabIndex:-1},{"aria-hidden":"true"})},t.resizeHandler=function(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")},t.dispose=function(){this.debouncedHandler_&&this.debouncedHandler_.cancel(),this.resizeObserver_&&(this.player_.el()&&this.resizeObserver_.unobserve(this.player_.el()),this.resizeObserver_.disconnect()),this.loadListener_&&this.off("load",this.loadListener_),this.el_&&this.el_.contentWindow&&this.unloadListener_&&this.unloadListener_.call(this.el_.contentWindow),this.ResizeObserver=null,this.resizeObserver=null,this.debouncedHandler_=null,this.loadListener_=null,a.prototype.dispose.call(this)},e}(pt));var En={trackingThreshold:20,liveTolerance:15};pt.registerComponent("LiveTracker",function(n){function e(e,t){var t=lt(En,t,{createEl:!1}),i=n.call(this,e,t)||this;return i.handleVisibilityChange_=function(e){return i.handleVisibilityChange(e)},i.trackLiveHandler_=function(){return i.trackLive_()},i.handlePlay_=function(e){return i.handlePlay(e)},i.handleFirstTimeupdate_=function(e){return i.handleFirstTimeupdate(e)},i.handleSeeked_=function(e){return i.handleSeeked(e)},i.seekToLiveEdge_=function(e){return i.seekToLiveEdge(e)},i.reset_(),i.on(i.player_,"durationchange",function(e){return i.handleDurationchange(e)}),i.on(i.player_,"canplay",function(){return i.toggleTracking()}),N&&"hidden"in document&&"visibilityState"in document&&i.on(document,"visibilitychange",i.handleVisibilityChange_),i}mt(e,n);var t=e.prototype;return t.handleVisibilityChange=function(){this.player_.duration()===1/0&&(document.hidden?this.stopTracking():this.startTracking())},t.trackLive_=function(){var e,t=this.player_.seekable();t&&t.length&&(e=Number(window.performance.now().toFixed(4)),t=-1===this.lastTime_?0:(e-this.lastTime_)/1e3,this.lastTime_=e,this.pastSeekEnd_=this.pastSeekEnd()+t,e=this.liveCurrentTime(),t=this.player_.currentTime(),t=this.player_.paused()||this.seekedBehindLive_||Math.abs(e-t)>this.options_.liveTolerance,(t=!this.timeupdateSeen_||e===1/0?!1:t)!==this.behindLiveEdge_&&(this.behindLiveEdge_=t,this.trigger("liveedgechange")))},t.handleDurationchange=function(){this.toggleTracking()},t.toggleTracking=function(){this.player_.duration()===1/0&&this.liveWindow()>=this.options_.trackingThreshold?(this.player_.options_.liveui&&this.player_.addClass("vjs-liveui"),this.startTracking()):(this.player_.removeClass("vjs-liveui"),this.stopTracking())},t.startTracking=function(){this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLiveHandler_,30),this.trackLive_(),this.on(this.player_,["play","pause"],this.trackLiveHandler_),this.timeupdateSeen_?this.on(this.player_,"seeked",this.handleSeeked_):(this.one(this.player_,"play",this.handlePlay_),this.one(this.player_,"timeupdate",this.handleFirstTimeupdate_)))},t.handleFirstTimeupdate=function(){this.timeupdateSeen_=!0,this.on(this.player_,"seeked",this.handleSeeked_)},t.handleSeeked=function(){var e=Math.abs(this.liveCurrentTime()-this.player_.currentTime());this.seekedBehindLive_=this.nextSeekedFromUser_&&2<e,this.nextSeekedFromUser_=!1,this.trackLive_()},t.handlePlay=function(){this.one(this.player_,"timeupdate",this.seekToLiveEdge_)},t.reset_=function(){this.lastTime_=-1,this.pastSeekEnd_=0,this.lastSeekEnd_=-1,this.behindLiveEdge_=!0,this.timeupdateSeen_=!1,this.seekedBehindLive_=!1,this.nextSeekedFromUser_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.off(this.player_,["play","pause"],this.trackLiveHandler_),this.off(this.player_,"seeked",this.handleSeeked_),this.off(this.player_,"play",this.handlePlay_),this.off(this.player_,"timeupdate",this.handleFirstTimeupdate_),this.off(this.player_,"timeupdate",this.seekToLiveEdge_)},t.nextSeekedFromUser=function(){this.nextSeekedFromUser_=!0},t.stopTracking=function(){this.isTracking()&&(this.reset_(),this.trigger("liveedgechange"))},t.seekableEnd=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.end(i));return t.length?t.sort()[t.length-1]:1/0},t.seekableStart=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.start(i));return t.length?t.sort()[0]:0}
4715,t.liveWindow=function(){var e=this.liveCurrentTime();return e===1/0?0:e-this.seekableStart()},t.isLive=function(){return this.isTracking()},t.atLiveEdge=function(){return!this.behindLiveEdge()},t.liveCurrentTime=function(){return this.pastSeekEnd()+this.seekableEnd()},t.pastSeekEnd=function(){var e=this.seekableEnd();return-1!==this.lastSeekEnd_&&e!==this.lastSeekEnd_&&(this.pastSeekEnd_=0),this.lastSeekEnd_=e,this.pastSeekEnd_},t.behindLiveEdge=function(){return this.behindLiveEdge_},t.isTracking=function(){return"number"==typeof this.trackingInterval_},t.seekToLiveEdge=function(){this.seekedBehindLive_=!1,this.atLiveEdge()||(this.nextSeekedFromUser_=!1,this.player_.currentTime(this.liveCurrentTime()))},t.dispose=function(){this.off(document,"visibilitychange",this.handleVisibilityChange_),this.stopTracking(),n.prototype.dispose.call(this)},e}(pt));function kn(e){if((n=e.el()).hasAttribute("src"))return e.triggerSourceset(n.src),1;var t=e.$$("source"),i=[],n="";if(t.length){for(var r=0;r<t.length;r++){var a=t[r].src;a&&-1===i.indexOf(a)&&i.push(a)}return!!i.length&&(1===i.length&&(n=i[0]),e.triggerSourceset(n),!0)}}function Cn(e,t){for(var i={},n=0;n<e.length&&!((i=Object.getOwnPropertyDescriptor(e[n],t))&&i.set&&i.get);n++);return i.enumerable=!0,i.configurable=!0,i}function In(a){var t,e,i,s=a.el();s.resetSourceWatch_||(t={},e=Cn([a.el(),window.HTMLMediaElement.prototype,window.Element.prototype,Ln],"innerHTML"),i=function(r){return function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=r.apply(s,t);return kn(a),n}},["append","appendChild","insertAdjacentHTML"].forEach(function(e){s[e]&&(t[e]=s[e],s[e]=i(t[e]))}),Object.defineProperty(s,"innerHTML",lt(e,{set:i(e.set)})),s.resetSourceWatch_=function(){s.resetSourceWatch_=null,Object.keys(t).forEach(function(e){s[e]=t[e]}),Object.defineProperty(s,"innerHTML",e)},a.one("sourceset",s.resetSourceWatch_))}function xn(i){var n,t,r,a;i.featuresSourceset&&((n=i.el()).resetSourceset_||(t=Cn([i.el(),window.HTMLMediaElement.prototype,Dn],"src"),r=n.setAttribute,a=n.load,Object.defineProperty(n,"src",lt(t,{set:function(e){e=t.set.call(n,e);return i.triggerSourceset(n.src),e}})),n.setAttribute=function(e,t){t=r.call(n,e,t);return/src/i.test(e)&&i.triggerSourceset(n.src),t},n.load=function(){var e=a.call(n);return kn(i)||(i.triggerSourceset(""),In(i)),e},n.currentSrc?i.triggerSourceset(n.currentSrc):kn(i)||In(i),n.resetSourceset_=function(){n.resetSourceset_=null,n.load=a,n.setAttribute=r,Object.defineProperty(n,"src",t),n.resetSourceWatch_&&n.resetSourceWatch_()}))}function An(t,i,n,e){function r(e){return Object.defineProperty(t,i,{value:e,enumerable:!0,writable:!0})}var a={configurable:!0,enumerable:!0,get:function(){var e=n();return r(e),e}};return(e=void 0===e?!0:e)&&(a.set=r),Object.defineProperty(t,i,a)}var Pn,Ln=Object.defineProperty({},"innerHTML",{get:function(){return this.cloneNode(!0).innerHTML},set:function(e){var t=document.createElement(this.nodeName.toLowerCase());t.innerHTML=e;for(var i=document.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return this.innerText="",window.Element.prototype.appendChild.call(this,i),this.innerHTML}}),Dn=Object.defineProperty({},"src",{get:function(){return this.hasAttribute("src")?Mt(window.Element.prototype.getAttribute.call(this,"src")):""},set:function(e){return window.Element.prototype.setAttribute.call(this,"src",e),e}}),On=function(l){function s(e,t){var i=l.call(this,e,t)||this,t=e.source,n=!1;if(t&&(i.el_.currentSrc!==t.src||e.tag&&3===e.tag.initNetworkState_)?i.setSource(t):i.handleLateInit_(i.el_),e.enableSourceset&&i.setupSourcesetHandling_(),i.isScrubbing_=!1,i.el_.hasChildNodes()){for(var r=i.el_.childNodes,a=r.length,s=[];a--;){var o=r[a];"track"===o.nodeName.toLowerCase()&&(i.featuresNativeTextTracks?(i.remoteTextTrackEls().addTrackElement_(o),i.remoteTextTracks().addTrack(o.track),i.textTracks().addTrack(o.track),n||i.el_.hasAttribute("crossorigin")||!Ut(o.src)||(n=!0)):s.push(o))}for(var u=0;u<s.length;u++)i.el_.removeChild(s[u])}return i.proxyNativeTracks_(),i.featuresNativeTextTracks&&n&&h.warn("Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\nThis may prevent text tracks from loading."),i.restoreMetadataTracksInIOSNativePlayer_(),(F||H||L)&&!0===e.nativeControlsForTouch&&i.setControls(!0),i.proxyWebkitFullscreen_(),i.triggerReady(),i}mt(s,l);var e=s.prototype;return e.dispose=function(){this.el_&&this.el_.resetSourceset_&&this.el_.resetSourceset_(),s.disposeMediaElement(this.el_),this.options_=null,l.prototype.dispose.call(this)},e.setupSourcesetHandling_=function(){xn(this)},e.restoreMetadataTracksInIOSNativePlayer_=function(){function e(){i=[];for(var e=0;e<n.length;e++){var t=n[e];"metadata"===t.kind&&i.push({track:t,storedMode:t.mode})}}var i,n=this.textTracks();e(),n.addEventListener("change",e),this.on("dispose",function(){return n.removeEventListener("change",e)});function r(){for(var e=0;e<i.length;e++){var t=i[e];"disabled"===t.track.mode&&t.track.mode!==t.storedMode&&(t.track.mode=t.storedMode)}n.removeEventListener("change",r)}this.on("webkitbeginfullscreen",function(){n.removeEventListener("change",e),n.removeEventListener("change",r),n.addEventListener("change",r)}),this.on("webkitendfullscreen",function(){n.removeEventListener("change",e),n.addEventListener("change",e),n.removeEventListener("change",r)})},e.overrideNative_=function(e,t){var i,n=this;t===this["featuresNative"+e+"Tracks"]&&(this[(i=e.toLowerCase())+"TracksListeners_"]&&Object.keys(this[i+"TracksListeners_"]).forEac
4715h(function(e){n.el()[i+"Tracks"].removeEventListener(e,n[i+"TracksListeners_"][e])}),this["featuresNative"+e+"Tracks"]=!t,this[i+"TracksListeners_"]=null,this.proxyNativeTracksForType_(i))},e.overrideNativeAudioTracks=function(e){this.overrideNative_("Audio",e)},e.overrideNativeVideoTracks=function(e){this.overrideNative_("Video",e)},e.proxyNativeTracksForType_=function(i){var e,t,n=this,r=ai[i],a=this.el()[r.getterName],s=this[r.getterName]();this["featuresNative"+r.capitalName+"Tracks"]&&a&&a.addEventListener&&(t=function(){for(var e=[],t=0;t<s.length;t++){for(var i=!1,n=0;n<a.length;n++)if(a[n]===s[t]){i=!0;break}i||e.push(s[t])}for(;e.length;)s.removeTrack(e.shift())},this[r.getterName+"Listeners_"]=e={change:function(e){var t={type:"change",target:s,currentTarget:s,srcElement:s};s.trigger(t),"text"===i&&n[si.remoteText.getterName]().trigger(t)},addtrack:function(e){s.addTrack(e.track)},removetrack:function(e){s.removeTrack(e.track)}},Object.keys(e).forEach(function(t){var i=e[t];a.addEventListener(t,i),n.on("dispose",function(e){return a.removeEventListener(t,i)})}),this.on("loadstart",t),this.on("dispose",function(e){return n.off("loadstart",t)}))},e.proxyNativeTracks_=function(){var t=this;ai.names.forEach(function(e){t.proxyNativeTracksForType_(e)})},e.createEl=function(){var e,t=this.options_.tag;t&&(this.options_.playerElIngest||this.movingMediaElementInDOM)||(t?(e=t.cloneNode(!0),t.parentNode&&t.parentNode.insertBefore(e,t),s.disposeMediaElement(t),t=e):(t=document.createElement("video"),e=lt({},this.options_.tag&&ae(this.options_.tag)),F&&!0===this.options_.nativeControlsForTouch||delete e.controls,re(t,b(e,{id:this.options_.techId,class:"vjs-tech"}))),t.playerId=this.options_.playerId),"undefined"!=typeof this.options_.preload&&oe(t,"preload",this.options_.preload),void 0!==this.options_.disablePictureInPicture&&(t.disablePictureInPicture=this.options_.disablePictureInPicture);for(var i=["loop","muted","playsinline","autoplay"],n=0;n<i.length;n++){var r=i[n],a=this.options_[r];"undefined"!=typeof a&&(a?oe(t,r,r):ue(t,r),t[r]=a)}return t},e.handleLateInit_=function(e){if(0!==e.networkState&&3!==e.networkState){if(0===e.readyState){var t=!1,i=function(){t=!0};this.on("loadstart",i);var n=function(){t||this.trigger("loadstart")};return this.on("loadedmetadata",n),void this.ready(function(){this.off("loadstart",i),this.off("loadedmetadata",n),t||this.trigger("loadstart")})}var r=["loadstart"];r.push("loadedmetadata"),2<=e.readyState&&r.push("loadeddata"),3<=e.readyState&&r.push("canplay"),4<=e.readyState&&r.push("canplaythrough"),this.ready(function(){r.forEach(function(e){this.trigger(e)},this)})}},e.setScrubbing=function(e){this.isScrubbing_=e},e.scrubbing=function(){return this.isScrubbing_},e.setCurrentTime=function(e){try{this.isScrubbing_&&this.el_.fastSeek&&V?this.el_.fastSeek(e):this.el_.currentTime=e}catch(e){h(e,"Video is not ready. (Video.js)")}},e.duration=function(){var t=this;return this.el_.duration===1/0&&A&&R&&0===this.el_.currentTime?(this.on("timeupdate",function e(){0<t.el_.currentTime&&(t.el_.duration===1/0&&t.trigger("durationchange"),t.off("timeupdate",e))}),NaN):this.el_.duration||NaN},e.width=function(){return this.el_.offsetWidth},e.height=function(){return this.el_.offsetHeight},e.proxyWebkitFullscreen_=function(){var e,t,i=this;"webkitDisplayingFullscreen"in this.el_&&(e=function(){this.trigger("fullscreenchange",{isFullscreen:!1}),this.el_.controls&&!this.options_.nativeControlsForTouch&&this.controls()&&(this.el_.controls=!1)},t=function(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",e),this.trigger("fullscreenchange",{isFullscreen:!0,nativeIOSFullscreen:!0}))},this.on("webkitbeginfullscreen",t),this.on("dispose",function(){i.off("webkitbeginfullscreen",t),i.off("webkitendfullscreen",e)}))},e.supportsFullScreen=function(){if("function"==typeof this.el_.webkitEnterFullScreen){var e=window.navigator&&window.navigator.userAgent||"";if(/Android/.test(e)||!/Chrome|Mac OS X 10.5/.test(e))return!0}return!1},e.enterFullScreen=function(){var e=this.el_;if(e.paused&&e.networkState<=e.HAVE_METADATA)Et(this.el_.play()),this.setTimeout(function(){e.pause();try{e.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}},0);else try{e.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}},e.exitFullScreen=function(){this.el_.webkitDisplayingFullscreen?this.el_.webkitExitFullScreen():this.trigger("fullscreenerror",new Error("The video is not fullscreen"))},e.requestPictureInPicture=function(){return this.el_.requestPictureInPicture()},e.src=function(e){if(void 0===e)return this.el_.src;this.setSrc(e)},e.reset=function(){s.resetMediaElement(this.el_)},e.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc},e.setControls=function(e){this.el_.controls=!!e},e.addTextTrack=function(e,t,i){return this.featuresNativeTextTracks?this.el_.addTextTrack(e,t,i):l.prototype.addTextTrack.call(this,e,t,i)},e.createRemoteTextTrack=function(e){if(!this.featuresNativeTextTracks)return l.prototype.createRemoteTextTrack.call(this,e);var t=document.createElement("track");return e.kind&&(t.kind=e.kind),e.label&&(t.label=e.label),(e.language||e.srclang)&&(t.srclang=e.language||e.srclang),e.default&&(t.default=e.default),e.id&&(t.id=e.id),e.src&&(t.src=e.src),t},e.addRemoteTextTrack=function(e,t){t=l.prototype.addRemoteTextTrack.call(this,e,t);return this.featuresNativeTextTracks&&this.el().appendChild(t),t},e.removeRemoteTextTrack=function(e){if(l.prototype.removeRemoteTextTrack.call(this,e),this.featuresNativeTextTracks)for(var t=this.$$("track"),i=t.length;i--;)e!==t[i]&&e!==t[i].track||this.el().removeChild(t[i])},e.getVideoPlaybackQuality=function(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();var e={};return"undefined"!=typeof this.el().webkitDroppedFrameCount&&"undefined"!=typeof this.el().webkitDecodedFrameCount&&(e.droppedVideoFrames=this.el().webkitDroppedFrameCount,e.totalVideoFrames=this.el().webkitDecodedFrameCount),window.performance&&"function"==typeof window.performance.now?e.creationTime=window.performance.now():window.performance&&window.performance.timing&&"number"==typeof window.performance.timing.navigationStart&&(e.creationTime=window.Date.now()-window.performance.timing.navigationStart),e},s}(ji);An(On,"TEST_VID",function(){if(X()){var e=document.createElement("video"),t=document.createElement("track");return t.kind="captions",t.srclang="en",t.label="English",e.appendChild(t),e}}),On.isSupported=function(){try{On.TEST_VID.volume=.5}catch(e){return!1}return!(!On.TEST_VID||!On.TEST_VID.canPlayType)},On.canPlayType=function(e){return On.TEST_VID.canPlayType(e)},On.canPlaySource=function(e,t){return On.canPlayType(e.type)},On.canControlVolume=function(){try{var e=On.TEST_VID.volume;On.TEST_VID.volume=e/2+.1;var t=e!==On.TEST_VID.volume;return t&&q?(window.setTimeout(function(){On&&On.prototype&&(On.prototype.featuresVolumeControl=e!==On.TEST_VID.volume)}),!1):t}catch(e){return!1}},On.canMuteVolume=function(){try{var e=On.TEST_VID.muted;return On.TEST_VID.muted=!e,On.TEST_VID.muted?oe(On.TEST_VID,"muted","muted"):ue(On.TEST_VID,"muted"),e!==On.TEST_VID.muted}catch(e){return!1}},On.canControlPlaybackRate=function(){if(A&&R&&M<58)return!1;try{var e=On.TEST_VID.playbackRate;return On.TEST_VID.playbackRate=e/2+.1,e!==On.TEST_VID.playbackRate}catch(e){return!1}},On.canOverrideAttributes=function(){try{var e=function(){};Object.defineProperty(document.createElement("video"),"src",{get:e,set:e}),Object.defineProperty(document.createElement("audio"),"src",{get:e,set:e}),Object.defineProperty(document.createElement("video"),"innerHTML",{get:e,set:e}),Object.defineProperty(document.createElement("audio"),"innerHTML",{get:e,set:e})}catch(e){return!1}return!0},On.supportsNativeTextTracks=function(){return V||q&&R},On.supportsNativeVideoTracks=function(){return!(!On.TEST_VID||!On.TEST_VID.videoTracks)},On.supportsNativeAudioTracks=function(){return!(!On.TEST_VID||!On.TEST_VID.audioTracks)},On.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],[["featuresMuteControl","canMuteVolume"],["featuresPlaybackRate","canControlPlaybackRate"],["featuresSourceset","canOverrideAttributes"],["featuresNativeTextTracks","supportsNativeTextTracks"],["featuresNativeVideoTracks","supportsNativeVideoTracks"],["featuresNativeAudioTracks","supportsNativeAudioTracks"]].forEac
vendor: 4,819 bytes, line 4715
4715h(function(e){var t=e[0],i=e[1];An(On.prototype,t,function(){return On[i]()},!0)}),On.prototype.featuresVolumeControl=On.canControlVolume(),On.prototype.movingMediaElementInDOM=!q,On.prototype.featuresFullscreenResize=!0,On.prototype.featuresProgressEvents=!0,On.prototype.featuresTimeupdateEvents=!0,On.patchCanPlayType=function(){4<=P&&!D&&!R&&(Pn=On.TEST_VID&&On.TEST_VID.constructor.prototype.canPlayType,On.TEST_VID.constructor.prototype.canPlayType=function(e){return e&&/^application\/(?:x-|vnd\.apple\.)mpegurl/i.test(e)?"maybe":Pn.call(this,e)})},On.unpatchCanPlayType=function(){var e=On.TEST_VID.constructor.prototype.canPlayType;return Pn&&(On.TEST_VID.constructor.prototype.canPlayType=Pn),e},On.patchCanPlayType(),On.disposeMediaElement=function(e){if(e){for(e.parentNode&&e.parentNode.removeChild(e);e.hasChildNodes();)e.removeChild(e.firstChild);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},On.resetMediaElement=function(e){if(e){for(var t=e.querySelectorAll("source"),i=t.length;i--;)e.removeChild(t[i]);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach(function(e){On.prototype[e]=function(){return this.el_[e]||this.el_.hasAttribute(e)}}),["muted","defaultMuted","autoplay","loop","playsinline"].forEach(function(t){On.prototype["set"+ut(t)]=function(e){(this.el_[t]=e)?this.el_.setAttribute(t,t):this.el_.removeAttribute(t)}}),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","disablePictureInPicture","played","networkState","readyState","videoWidth","videoHeight","crossOrigin"].forEach(function(e){On.prototype[e]=function(){return this.el_[e]}}),["volume","src","poster","preload","playbackRate","defaultPlaybackRate","disablePictureInPicture","crossOrigin"].forEach(function(t){On.prototype["set"+ut(t)]=function(e){this.el_[t]=e}}),["pause","load","play"].forEach(function(e){On.prototype[e]=function(){return this.el_[e]()}}),ji.withSourceHandlers(On),On.nativeSourceHandler={},On.nativeSourceHandler.canPlayType=function(e){try{return On.TEST_VID.canPlayType(e)}catch(e){return""}},On.nativeSourceHandler.canHandleSource=function(e,t){if(e.type)return On.nativeSourceHandler.canPlayType(e.type);if(e.src){e=Nt(e.src);return On.nativeSourceHandler.canPlayType("video/"+e)}return""},On.nativeSourceHandler.handleSource=function(e,t,i){t.setSrc(e.src)},On.nativeSourceHandler.dispose=function(){},On.registerSourceHandler(On.nativeSourceHandler),ji.registerTech("Html5",On);var Rn=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],Mn={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},Nn=["tiny","xsmall","small","medium","large","xlarge","huge"],Un={};Nn.forEach(function(e){var t="x"===e.charAt(0)?"x-"+e.substring(1):e;Un[e]="vjs-layout-"+t});var Bn={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0},Fn=function(c){function o(e,t,i){var n,r;if(e.id=e.id||t.id||"vjs_video_"+Pe++,(t=b(o.getTagSettings(e),t)).initChildren=!1,t.createEl=!1,t.evented=!1,t.reportTouchActivity=!1,!t.language)if("function"==typeof e.closest){var a=e.closest("[lang]");a&&a.getAttribute&&(t.language=a.getAttribute("lang"))}else for(var s=e;s&&1===s.nodeType;){if(ae(s).hasOwnProperty("lang")){t.language=s.getAttribute("lang");break}s=s.parentNode}if((n=c.call(this,null,t,i)||this).boundDocumentFullscreenChange_=function(e){return n.documentFullscreenChange_(e)},n.boundFullWindowOnEscKey_=function(e){return n.fullWindowOnEscKey(e)},n.boundUpdateStyleEl_=function(e){return n.updateStyleEl_(e)},n.boundApplyInitTime_=function(e){return n.applyInitTime_(e)},n.boundUpdateCurrentBreakpoint_=function(e){return n.updateCurrentBreakpoint_(e)},n.boundHandleTechClick_=function(e){return n.handleTechClick_(e)},n.boundHandleTechDoubleClick_=function(e){return n.handleTechDoubleClick_(e)},n.boundHandleTechTouchStart_=function(e){return n.handleTechTouchStart_(e)},n.boundHandleTechTouchMove_=function(e){return n.handleTechTouchMove_(e)},n.boundHandleTechTouchEnd_=function(e){return n.handleTechTouchEnd_(e)},n.boundHandleTechTap_=function(e){return n.handleTechTap_(e)},n.isFullscreen_=!1,n.log=p(n.id_),n.fsApi_=l,n.isPosterFromTech_=!1,n.queuedCallbacks_=[],n.isReady_=!1,n.hasStarted_=!1,n.userActive_=!1,n.debugEnabled_=!1,!n.options_||!n.options_.techOrder||!n.options_.techOrder.length)throw new Error("No techOrder specified. Did you overwrite videojs.options instead of just changing the properties you want to override?");n.tag=e,n.tagAttributes=e&&ae(e),n.language(n.options_.language),t.languages?(r={}
4715,Object.getOwnPropertyNames(t.languages).forEach(function(e){r[e.toLowerCase()]=t.languages[e]}),n.languages_=r):n.languages_=o.prototype.options_.languages,n.resetCache_(),n.poster_=t.poster||"",n.controls_=!!t.controls,e.controls=!1,e.removeAttribute("controls"),n.changingSrc_=!1,n.playCallbacks_=[],n.playTerminatedQueue_=[],e.hasAttribute("autoplay")?n.autoplay(!0):n.autoplay(n.options_.autoplay),t.plugins&&Object.keys(t.plugins).forEach(function(e){if("function"!=typeof n[e])throw new Error('plugin "'+e+'" does not exist')}),n.scrubbing_=!1,n.el_=n.createEl(),rt(ft(n),{eventBusKey:"el_"}),n.fsApi_.requestFullscreen&&(Be(document,n.fsApi_.fullscreenchange,n.boundDocumentFullscreenChange_),n.on(n.fsApi_.fullscreenchange,n.boundDocumentFullscreenChange_)),n.fluid_&&n.on(["playerreset","resize"],n.boundUpdateStyleEl_);i=lt(n.options_);t.plugins&&Object.keys(t.plugins).forEach(function(e){n[e](t.plugins[e])}),t.debug&&n.debug(!0),n.options_.playerOptions=i,n.middleware_=[],n.playbackRates(t.playbackRates),n.initChildren(),n.isAudio("audio"===e.nodeName.toLowerCase()),n.controls()?n.addClass("vjs-controls-enabled"):n.addClass("vjs-controls-disabled"),n.el_.setAttribute("role","region"),n.isAudio()?n.el_.setAttribute("aria-label",n.localize("Audio Player")):n.el_.setAttribute("aria-label",n.localize("Video Player")),n.isAudio()&&n.addClass("vjs-audio"),n.flexNotSupported_()&&n.addClass("vjs-no-flex"),F&&n.addClass("vjs-touch-enabled"),q||n.addClass("vjs-workinghover"),o.players[n.id_]=ft(n);e=u.split(".")[0];return n.addClass("vjs-v"+e),n.userActive(!0),n.reportUserActivity(),n.one("play",function(e){return n.listenForUserActivity_(e)}),n.on("stageclick",function(e){return n.handleStageClick_(e)}),n.on("keydown",function(e){return n.handleKeyDown(e)}),n.on("languagechange",function(e){return n.handleLanguagechange(e)}),n.breakpoints(n.options_.breakpoints),n.responsive(n.options_.responsive),n}mt(o,c);var e=o.prototype;return e.dispose=function(){var t=this;this.trigger("dispose"),this.off("dispose"),Fe(document,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),Fe(document,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),o.players[this.id_]=null,this.tag&&this.tag.player&&(this.tag.player=null),this.el_&&this.el_.player&&(this.el_.player=null),this.tech_&&(this.tech_.dispose(),this.isPosterFromTech_=!1,this.poster_=""),this.playerElIngest_&&(this.playerElIngest_=null),this.tag&&(this.tag=null),qi[this.id()]=null,oi.names.forEach(function(e){e=oi[e],e=t[e.getterName]();e&&e.off&&e.off()}),c.prototype.dispose.call(this)},e.createEl=function(){var t,i=this.tag,e=this.playerElIngest_=i.parentNode&&i.parentNode.hasAttribute&&i.parentNode.hasAttribute("data-vjs-player"),n="video-js"===this.tag.tagName.toLowerCase();e?t=this.el_=i.parentNode:n||(t=this.el_=c.prototype.createEl.call(this,"div"));var r,a,s=ae(i);if(n){for(t=this.el_=i,i=this.tag=document.createElement("video");t.children.length;)i.appendChild(t.firstChild);ee(t,"video-js")||te(t,"video-js"),t.appendChild(i),e=this.playerElIngest_=t,Object.keys(t).forEach(function(e){try{i[e]=t[e]}catch(e){}})}i.setAttribute("tabindex","-1"),s.tabindex="-1",(N||R&&B)&&(i.setAttribute("role","application"),s.role="application"),i.removeAttribute("width"),i.removeAttribute("height"),"width"in s&&delete s.width,"height"in s&&delete s.height,Object.getOwnPropertyNames(s).forEach(function(e){n&&"class"===e||t.setAttribute(e,s[e]),n&&i.setAttribute(e,s[e])}),i.playerId=i.id,i.id+="_html5_api",i.className="vjs-tech",(i.player=t.player=this).addClass("vjs-paused"),!0!==window.VIDEOJS_NO_DYNAMIC_STYLE&&(this.styleEl_=xe("vjs-styles-dimensions"),r=Te(".vjs-styles-defaults"),(a=Te("head")).insertBefore(this.styleEl_,r?r.nextSibling:a.firstChild)),this.fill_=!1,this.fluid_=!1,this.width(this.options_.width),this.height(this.options_.height),this.fill(this.options_.fill),this.fluid(this.options_.fluid),this.aspectRatio(this.options_.aspectRatio),this.crossOrigin(this.options_.crossOrigin||this.options_.crossorigin);for(var o=i.getElementsByTagName("a"),u=0;u<o.length;u++){var l=o.item(u);te(l,"vjs-hidden"),l.setAttribute("hidden","hidden")}return i.initNetworkState_=i.networkState,i.parentNode&&!e&&i.parentNode.insertBefore(t,i),Z(i,t),this.children_.unshift(i),this.el_.setAttribute("lang",this.language_),this.el_.setAttribute("translate","no"),this.el_=t},e.crossOrigin=function(e){if(!e)return this.techGet_("crossOrigin");"anonymous"===e||"use-credentials"===e?this.techCall_("setCrossOrigin",e):h.warn('crossOrigin must be "anonymous" or "use-credentials", given "'+e+'"')},e.width=function(e){return this.dimension("width",e)},e.height=function(e){return this.dimension("height",e)},e.dimension=function(e,t){var i=e+"_";if(void 0===t)return this[i]||0;if(""===t||"auto"===t)return this[i]=void 0,void this.updateStyleEl_();var n=parseFloat(t);isNaN(n)?h.error('Improper value "'+t+'" supplied for for '+e):(this[i]=n,this.updateStyleEl_())},e.fluid=function(e){var t,i=this;if(void 0===e)return!!this.fluid_;this.fluid_=!!e,it(this)&&this.off(["playerreset","resize"],this.boundUpdateStyleEl_),e?(this.addClass("vjs-fluid"),this.fill(!1),t=function(){i.on(["playerreset","resize"],i.boundUpdateStyleEl_)},it(e=this)?t():(e.eventedCallbacks||(e.eventedCallbacks=[]),e.eventedCallbacks.push(t))):this.removeClass("vjs-fluid"),this.updateStyleEl_()},e.fill=function(e){if(void 0===e)return!!this.fill_;this.fill_=!!e,e?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")},e.aspectRatio=function(e){if(void 0===e)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(e))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=e,this.fluid(!0),this.updateStyleEl_()},e.updateStyleEl_=function(){var e,t,i,n;!0!==window.VIDEOJS_NO_DYNAMIC_STYLE?(n=(i=(void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:0<this.videoWidth()?this.videoWidth()+":"+this.videoHeight():"16:9").split(":"))[1]/i[0],e=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/n:this.videoWidth()||300,t=void 0!==this.height_?this.height_:e*n,i=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(i),Ae(this.styleEl_,"\n ."+i+" {\n width: "+e+"px;\n height: "+t+"px;\n }\n\n ."+i+".vjs-fluid {\n padding-top: "+100*n+"%;\n }\n ")):(t="number"==typeof this.width_?this.width_:this.options_.width,i="number"==typeof this.height_?this.height_:this.options_.height,(n=this.tech_&&this.tech_.el())&&
4715(0<=t&&(n.width=t),0<=i&&(n.height=i)))},e.loadTech_=function(e,t){var i=this;this.tech_&&this.unloadTech_();var n=ut(e),r=e.charAt(0).toLowerCase()+e.slice(1);"Html5"!==n&&this.tag&&(ji.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=n,this.isReady_=!1;var a=this.autoplay(),s={source:t,autoplay:a="string"==typeof this.autoplay()||!0===this.autoplay()&&this.options_.normalizeAutoplay?!1:a,nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:this.id()+"_"+r+"_api",playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,disablePictureInPicture:this.options_.disablePictureInPicture,muted:this.options_.muted,poster:this.poster(),language:this.language(),playerElIngest:this.playerElIngest_||!1,"vtt.js":this.options_["vtt.js"],canOverridePoster:!!this.options_.techCanOverridePoster,enableSourceset:this.options_.enableSourceset,Promise:this.options_.Promise};oi.names.forEach(function(e){e=oi[e];s[e.getterName]=i[e.privateName]}),b(s,this.options_[n]),b(s,this.options_[r]),b(s,this.options_[e.toLowerCase()]),this.tag&&(s.tag=this.tag),t&&t.src===this.cache_.src&&0<this.cache_.currentTime&&(s.startTime=this.cache_.currentTime);e=ji.getTech(e);if(!e)throw new Error("No Tech named '"+n+"' exists! '"+n+"' should be registered using videojs.registerTech()'");this.tech_=new e(s),this.tech_.ready(Ve(this,this.handleTechReady_),!0),It(this.textTracksJson_||[],this.tech_),Rn.forEach(function(t){i.on(i.tech_,t,function(e){return i["handleTech"+ut(t)+"_"](e)})}),Object.keys(Mn).forEach(function(t){i.on(i.tech_,t,function(e){0===i.tech_.playbackRate()&&i.tech_.seeking()?i.queuedCallbacks_.push({callback:i["handleTech"+Mn[t]+"_"].bind(i),event:e}):i["handleTech"+Mn[t]+"_"](e)})}),this.on(this.tech_,"loadstart",function(e){return i.handleTechLoadStart_(e)}),this.on(this.tech_,"sourceset",function(e){return i.handleTechSourceset_(e)}),this.on(this.tech_,"waiting",function(e){return i.handleTechWaiting_(e)}),this.on(this.tech_,"ended",function(e){return i.handleTechEnded_(e)}),this.on(this.tech_,"seeking",function(e){return i.handleTechSeeking_(e)}),this.on(this.tech_,"play",function(e){return i.handleTechPlay_(e)}),this.on(this.tech_,"firstplay",function(e){return i.handleTechFirstPlay_(e)}),this.on(this.tech_,"pause",function(e){return i.handleTechPause_(e)}),this.on(this.tech_,"durationchange",function(e){return i.handleTechDurationChange_(e)}),this.on(this.tech_,"fullscreenchange",function(e,t){return i.handleTechFullscreenChange_(e,t)}),this.on(this.tech_,"fullscreenerror",function(e,t){return i.handleTechFullscreenError_(e,t)}),this.on(this.tech_,"enterpictureinpicture",function(e){return i.handleTechEnterPictureInPicture_(e)}),this.on(this.tech_,"leavepictureinpicture",function(e){return i.handleTechLeavePictureInPicture_(e)}),this.on(this.tech_,"error",function(e){return i.handleTechError_(e)}),this.on(this.tech_,"posterchange",function(e){return i.handleTechPosterChange_(e)}),this.on(this.tech_,"textdata",function(e){return i.handleTechTextData_(e)}),this.on(this.tech_,"ratechange",function(e){return i.handleTechRateChange_(e)}),this.on(this.tech_,"loadedmetadata",this.boundUpdateStyleEl_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===n&&this.tag||Z(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)},e.unloadTech_=function(){var t=this;oi.names.forEach(function(e){e=oi[e];t[e.privateName]=t[e.getterName]()}),this.textTracksJson_=Ct(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1},e.tech=function(e){return void 0===e&&h.warn("Using the tech directly can be dangerous. I hope you know
4715what you're doing.\nSee https://github.com/videojs/video.js/issues/2617 for more info.\n"),this.tech_},e.addTechControlsListeners_=function(){this.removeTechControlsListeners_(),this.on(this.tech_,"click",this.boundHandleTechClick_),this.on(this.tech_,"dblclick",this.boundHandleTechDoubleClick_),this.on(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.on(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.on(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.on(this.tech_,"tap",this.boundHandleTechTap_)},e.removeTechControlsListeners_=function(){this.off(this.tech_,"tap",this.boundHandleTechTap_),this.off(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.off(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.off(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.off(this.tech_,"click",this.boundHandleTechClick_),this.off(this.tech_,"dblclick",this.boundHandleTechDoubleClick_)},e.handleTechReady_=function(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()},e.handleTechLoadStart_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):(this.trigger("loadstart"),this.trigger("firstplay")),this.manualAutoplay_(!0===this.autoplay()&&this.options_.normalizeAutoplay?"play":this.autoplay())},e.manualAutoplay_=function(e){var n=this;if(this.tech_&&"string"==typeof e){var t,i=function(){var e=n.muted();n.muted(!0);function t(){n.muted(e)}n.playTerminatedQueue_.push(t);var i=n.play();if(wt(i))return i.catch(function(e){throw t(),new Error("Rejection at manualAutoplay. Restoring muted value. "+(e||""))})};if("any"!==e||this.muted()?t="muted"!==e||this.muted()?this.play():i():wt(t=this.play())&&(t=t.catch(i)),wt(t))return t.then(function(){n.trigger({type:"autoplay-success",autoplay:e})}).catch(function(){n.trigger({type:"autoplay-failure",autoplay:e})})}},e.updateSourceCaches_=function(e){var t=e=void 0===e?"":e,i="";"string"!=typeof t&&(t=e.src,i=e.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],t&&!i&&(i=function(e,t){if(!t)return"";if(e.cache_.source.src===t&&e.cache_.source.type)return e.cache_.source.type;var i=e.cache_.sources.filter(function(e){return e.src===t});if(i.length)return i[0].type;for(var n=e.$$("source"),r=0;r<n.length;r++){var a=n[r];if(a.type&&a.src&&a.src===t)return a.type}return $i(t)}(this,t)),this.cache_.source=lt({},e,{src:t,type:i});for(var i=this.cache_.sources.filter(function(e){return e.src&&e.src===t}),n=[],r=this.$$("source"),a=[],s=0;s<r.length;s++){var o=ae(r[s]);n.push(o),o.src&&o.src===t&&a.push(o.src)}a.length&&!i.length?this.cache_.sources=n:i.length||(this.cache_.sources=[this.cache_.source]),this.cache_.src=t},e.handleTechSourceset_=function(e){var t,i,n,r=this;this.changingSrc_||(t=function(e){return r.updateSourceCaches_(e)},i=this.currentSource().src,n=e.src,i&&!/^blob:/.test(i)&&/^blob:/.test(n)&&(this.lastSource_&&(this.lastSource_.tech===n||this.lastSource_.player===i)||(t=function(){})),t(n),e.src||this.tech_.any(["sourceset","loadstart"],function(e){"sourceset"!==e.type&&(e=r.techGet("currentSrc"),r.lastSource_.tech=e,r.updateSourceCaches_(e))})),this.lastSource_={player:this.currentSource().src,tech:e.src},this.trigger({src:e.src,type:"sourceset"})},e.hasStarted=function(e){if(void 0===e)return this.hasStarted_;e!==this.hasStarted_&&(this.hasStarted_=e,this.hasStarted_?(this.addClass("vjs-has-started"),this.trigger("firstplay")):this.removeClass("vjs-has-started"))},e.handleTechPlay_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")},e.handleTechRateChange_=function(){0<this.tech_.playbackRate()&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach(function(e){return e.callback(e.event)}),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")},e.handleTechWaiting_=function(){var t=this;this.addClass("vjs-waiting"),this.trigger("waiting");var i=this.currentTime();this.on("timeupdate",function e(){i!==t.currentTime()&&(t.removeClass("vjs-waiting"),t.off("timeupdate",e))})},e.handleTechCanPlay_=function(){this.removeClass("vjs-waiting"),this.trigger("canplay")},e.handleTechCanPlayThrough_=function(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")},e.handleTechPlaying_=function(){this.removeClass("vjs-waiting"),this.trigger("playing")},e.handleTechSeeking_=function(){this.addClass("vjs-seeking"),this.trigger("seeking")},e.handleTechSeeked_=function(){this.removeClass("vjs-seeking"),this.removeClass("vjs-ended"),this.trigger("seeked")},e.handleTechFirstPlay_=function(){this.options_.starttime&&(h.warn("Passing the `starttime` option to the player will be deprecated
4715in 6.0"),this.currentTime(this.options_.starttime)),this.addClass("vjs-has-started"),this.trigger("firstplay")},e.handleTechPause_=function(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")},e.handleTechEnded_=function(){this.addClass("vjs-ended"),this.removeClass("vjs-waiting"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")},e.handleTechDurationChange_=function(){this.duration(this.techGet_("duration"))},e.handleTechClick_=function(e){this.controls_&&(void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.click&&!1===this.options_.userActions.click||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.click?this.options_.userActions.click.call(this,e):this.paused()?Et(this.play()):this.pause()))},e.handleTechDoubleClick_=function(t){this.controls_&&(Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),function(e){return e.contains(t.target)})||void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.doubleClick&&!1===this.options_.userActions.doubleClick||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.doubleClick?this.options_.userActions.doubleClick.call(this,t):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen()))},e.handleTechTap_=function(){this.userActive(!this.userActive())},e.handleTechTouchStart_=function(){this.userWasActive=this.userActive()},e.handleTechTouchMove_=function(){this.userWasActive&&this.reportUserActivity()},e.handleTechTouchEnd_=function(e){e.cancelable&&e.preventDefault()},e.handleStageClick_=function(){this.reportUserActivity()},e.toggleFullscreenClass_=function(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")},e.documentFullscreenChange_=function(e){var t=e.target.player;t&&t!==this||(e=this.el(),!(t=document[this.fsApi_.fullscreenElement]===e)&&e.matches?t=e.matches(":"+this.fsApi_.fullscreen):!t&&e.msMatchesSelector&&(t=e.msMatchesSelector(":"+this.fsApi_.fullscreen)),this.isFullscreen(t))},e.handleTechFullscreenChange_=function(e,t){var i=this;t&&(t.nativeIOSFullscreen&&(this.addClass("vjs-ios-native-fs"),this.tech_.one("webkitendfullscreen",function(){i.removeClass("vjs-ios-native-fs")})),this.isFullscreen(t.isFullscreen))},e.handleTechFullscreenError_=function(e,t){this.trigger("fullscreenerror",t)},e.togglePictureInPictureClass_=function(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")},e.handleTechEnterPictureInPicture_=function(e){this.isInPictureInPicture(!0)},e.handleTechLeavePictureInPicture_=function(e){this.isInPictureInPicture(!1)},e.handleTechError_=function(){var e=this.tech_.error();this.error(e)},e.handleTechTextData_=function(){this.trigger("textdata",1<arguments.length?arguments[1]:null)},e.getCache=function(){return this.cache_},e.resetCache_=function(){this.cache_={currentTime:0,initTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],playbackRates:[],volume:1}},e.techCall_=function(n,r){this.ready(function(){if(n in Xi)return e=this.middleware_,t=this.tech_,i=r,t[t=n](e.reduce(Yi(t),i));if(n in Ki)return Gi(this.middleware_,this.tech_,n,r);var e,t,i;try{this.tech_&&this.tech_[n](r)}catch(e){throw h(e),e}},!0)},e.techGet_=function(t){if(this.tech_&&this.tech_.isReady_){if(t in zi)return e=this.middleware_,i=this.tech_,n=t,e.reduceRight(Yi(n),i[n]());if(t in Ki)return Gi(this.middleware_,this.tech_,t);var e,i,n;try{return this.tech_[t]()}catch(e){if(void 0===this.tech_[t])throw h("Video.js: "+t+" method not defined for "+this.techName_+" playback technology.",e),e;if("TypeError"===e.name)throw h("Video.js: "+t+" unavailable on "+this.techName_+" playback technology element.",e),this.tech_.isReady_=!1,e;throw h(e),e}}},e.play=function(){var t=this,e=this.options_.Promise||window.Promise;return e?new e(function(e){t.play_(e)}):this.play_()},e.play_=function(e){var t=this;this.playCallbacks_.push(e=void 0===e?Et:e);e=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc()));if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!e)return this.waitToPlay_=function(e){t.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(e||!V&&!q||this.load());e=this.techGet_("play");null===e?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(e)},e.runPlayTerminatedQueue_=function(){var e=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],e.forEach(function(e){e()})},e.runPlayCallbacks_=function(t){var e=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],e.forEach(function(e){e(t)})},e.pause=function(){this.techCall_("pause")},e.paused=function(){return!1!==this.techGet_("paused")},e.played=function(){return this.techGet_("played")||vt(0,0)},e.scrubbing=function(e){if("undefined"==typeof e)return this.scrubbing_;this.scrubbing_=!!e,this.techCall_("setScrubbing",this.scrubbing_),e?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")},e.currentTime=function(e){return"undefined"!=typeof e?(e<0&&(e=0),this.isReady_&&!this.changingSrc_&&this.tech_&&this.tech_.isReady_?(this.techCall_("setCurrentTime",e),void(this.cache_.initTime=0)):(this.cache_.initTime=e,this.off("canplay",this.boundApplyInitTime_),void this.one("canplay",this.boundApplyInitTime_))):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)},e.applyInitTime_=function(){this.currentTime(this.cache_.initTime)},e.duration=function(e){if(void 0===e)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(e=(e=parseFloat(e))<0?1/0:e)!==this.cache_.duration&&((this.cache_.duration=e)===1/0?this.addClass("vjs-live"):this.removeClass("vjs-live"),isNaN(e)||this.trigger("durationchange"))},e.remainingTime=function(){return this.duration()-this.currentTime()},e.remainingTimeDisplay=function(){return Math.floor(this.duration())-Math.floor(this.currentTime())},e.buffered=function(){var e;return e=!(e=this.techGet_("buffered"))||!e.length?vt(0,0):e},e.bufferedPercent=function(){return _t(this.buffered(),this.duration())},e.bufferedEnd=function(){var e=this.buffered(),t=this.duration(),e=e.end(e.length-1);return e=t<e?t:e},e.volume=function(e){var t;return void 0!==e?(t=Math.max(0,Math.min(1,parseFloat(e))),this.cache_.volume=t,this.techCall_("setVolume",t),void(0<t&&this.lastVolume_(t))):(t=parseFloat(this.techGet_("volume")),isNaN(t)?1:t)},e.muted=function(e){if(void 0===e)return this.techGet_("muted")||!1;this.techCall_("setMuted",e)},e.defaultMuted=function(e){return void 0!==e?this.techCall_("setDefaultMuted",e):this.techGet_("defaultMuted")||!1},e.lastVolume_=function(e){if(void 0===e||0===e)return this.cache_.lastVolume;this.cache_.lastVolume=e},e.supportsFullScreen=function(){return this.techGet_("supportsFullScreen")||!1},e.isFullscreen=function(e){if(void 0===e)return this.isFullscreen_;var t=this.isFullscreen_;this.isFullscreen_=Boolean(e),this.isFullscreen_!==t&&this.fsApi_.prefixed&&this.trigger("fullscreenchange"),this.toggleFullscreenClass_()},e.requestFullscreen=function(s){var e=this.options_.Promise||window.Promise;if(e){var o=this;return new e(function(e,i){function n(){o.off("fullscreenerror",r),o.off("fullscreenchange",t)}function t(){n(),e()}function r(e,t){n(),i(t)}o.one("fullscreenchange",t),o.one("fullscreenerror",r);var a=o.requestFullscreenHelper_(s);a&&(a.then(n,n),a.then(e,i))})}return this.requestFullscreenHelper_()},e.requestFullscreenHelper_=function(e){var t=this;if(this.fsApi_.prefixed||(i=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==e&&(i=e)),this.fsApi_.requestFullscreen){var i=this.el_[this.fsApi_.requestFullscreen](i);return i&&i.then(function(){return t.isFullscreen(!0)},function(){return t.isFullscreen(!1)}),i}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("enterFullScreen"):this.enterFullWindow()},e.exitFullscreen=function(){var e=this.options_.Promise||window.Promise;if(e){var s=this;return new e(function(e,i){function n(){s.off("fullscreenerror",r),s.off("fullscreenchange",t)}function t(){n(),e()}function r(e,t){n(),i(t)}s.one("fullscreenchange",t),s.one("fullscreenerror",r);var a=s.exitFullscreenHelper_();a&&(a.then(n,n),a.then(e,i))})}return this.exitFullscreenHelper_()},e.exitFullscreenHelper_=function(){var e=this;if(this.fsApi_.requestFullscreen){var t=document[this.fsApi_.exitFullscreen]();return t&&Et(t.then(function(){return e.isFullscreen(!1)})),t}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("exitFullScreen"):this.exitFullWindow()},e.enterFullWindow=function(){this.isFullscreen(!0),this.isFullWindow=!0,this.docOrigOverflow=document.documentElement.style.overflow,Be(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow="hidden",te(document.body,"vjs-full-window"),this.trigger("enterFullWindow")},e.fullWindowOnEscKey=function(e){ht.isEventKey(e,"Esc")&&!0===this.isFullscreen()&&(this.isFullWindow?this.exitFullWindow():this.exitFullscreen())},e.exitFullWindow=function(){this.isFullscreen(!1),this.isFullWindow=!1,Fe(document,"keydown",this.boundFullWindowOnEscKey_),document.documentElement.style.overflow=this.docOrigOverflow,ie(document.body,"vjs-full-window"),this.trigger("exitFullWindow")},e.disablePictureInPicture=function(e){if(void 0===e)return this.techGet_("disablePictureInPicture");this.techCall_("setDisablePictureInPicture",e),this.options_.disablePictureInPicture=e,this.trigger("disablepictureinpicturechanged")},e.isInPictureInPicture=function(e){return void 0!==e?(this.isInPictureInPicture_=!!e,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_},e.requestPictureInPicture=function(){if("pictureInPictureEnabled"in document&&!1===this.disablePictureInPicture())return this.techGet_("requestPictureInPicture")},e.exitPictureInPicture=function(){if("pictureInPictureEnabled"in document)return document.exitPictureInPicture()},e.handleKeyDown=function(e){var t=this.options_.userActions;t&&t.hotkeys&&(function(e){var t=e.tagName.toLowerCase();if(e.isContentEditable)return!0;
4715if("input"===t)return-1===["button","checkbox","hidden","radio","reset","submit"].indexOf(e.type);return-1!==["textarea"].indexOf(t)}(this.el_.ownerDocument.activeElement)||("function"==typeof t.hotkeys?t.hotkeys.call(this,e):this.handleHotkeys(e)))},e.handleHotkeys=function(e){var t=this.options_.userActions?this.options_.userActions.hotkeys:{},i=t.fullscreenKey,n=t.muteKey,n=void 0===n?function(e){return ht.isEventKey(e,"m")}:n,t=t.playPauseKey,t=void 0===t?function(e){return ht.isEventKey(e,"k")||ht.isEventKey(e,"Space")}:t;(void 0===i?function(e){return ht.isEventKey(e,"f")}:i).call(this,e)?(e.preventDefault(),e.stopPropagation(),i=pt.getComponent("FullscreenToggle"),!1!==document[this.fsApi_.fullscreenEnabled]&&i.prototype.handleClick.call(this,e)):n.call(this,e)?(e.preventDefault(),e.stopPropagation(),pt.getComponent("MuteToggle").prototype.handleClick.call(this,e)):t.call(this,e)&&(e.preventDefault(),e.stopPropagation(),pt.getComponent("PlayToggle").prototype.handleClick.call(this,e))},e.canPlayType=function(e){for(var t,i=0,n=this.options_.techOrder;i<n.length;i++){var r=n[i],a=ji.getTech(r);if(a=a||pt.getComponent(r)){if(a.isSupported()&&(t=a.canPlayType(e)))return t}else h.error('The "'+r+'" tech is undefined. Skipped browser support check for that tech.')}return""},e.selectSource=function(e){function t(e,i,n){var r;return e.some(function(t){return i.some(function(e){if(r=n(t,e))return!0})}),r}var i,n=this,r=this.options_.techOrder.map(function(e){return[e,ji.getTech(e)]}).filter(function(e){var t=e[0],e=e[1];return e?e.isSupported():(h.error('The "'+t+'" tech is undefined. Skipped browser support check for that tech.'),!1)}),a=function(e,t){var i=e[0];if(e[1].canPlaySource(t,n.options_[i.toLowerCase()]))return{source:t,tech:i}},a=this.options_.sourceOrder?t(e,r,(i=a,function(e,t){return i(t,e)})):t(r,e,a);return a||!1},e.handleSrc_=function(e,n){var r=this;if("undefined"==typeof e)return this.cache_.src||"";this.resetRetryOnError_&&this.resetRetryOnError_();var t,i,a=Ji(e);a.length?(this.changingSrc_=!0,n||(this.cache_.sources=a),this.updateSourceCaches_(a[0]),Wi(this,a[0],function(e,t){var i;return r.middleware_=t,n||(r.cache_.sources=a),r.updateSourceCaches_(e),r.src_(e)?1<a.length?r.handleSrc_(a.slice(1)):(r.changingSrc_=!1,r.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0),void r.triggerReady()):(t=t,i=r.tech_,void t.forEach(function(e){return e.setTech&&e.setTech(i)}))}),this.options_.retryOnError&&1<a.length&&(i=function(){r.off("error",t)},this.one("error",t=function(){r.error(null),r.handleSrc_(a.slice(1),!0)}),this.one("playing",i),this.resetRetryOnError_=function(){r.off("error",t),r.off("playing",i)})):this.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0)},e.src=function(e){return this.handleSrc_(e,!1)},e.src_=function(e){var t,i,n=this,r=this.selectSource([e]);return!r||(t=r.tech,i=this.techName_,ut(t)!==ut(i)?(this.changingSrc_=!0,this.loadTech_(r.tech,r.source),this.tech_.ready(function(){n.changingSrc_=!1})):this.ready(function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",e):this.techCall_("src",e.src),this.changingSrc_=!1},!0),!1)},e.load=function(){this.techCall_("load")},e.reset=function(){var e=this,t=this.options_.Promise||window.Promise;this.paused()||!t?this.doReset_():Et(this.play().then(function(){return e.doReset_()}))},e.doReset_=function(){this.tech_&&this.tech_.clearTracks("text"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),it(this)&&this.trigger("playerreset")},e.resetControlBarUI_=function(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()},e.resetProgressBar_=function(){this.currentTime(0);var e=this.controlBar,t=e.durationDisplay,e=e.remainingTimeDisplay;t&&t.updateContent(),e&&e.updateContent()},e.resetPlaybackRate_=function(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()},e.resetVolumeBar_=function(){this.volume(1),this.trigger("volumechange")},e.currentSources=function(){var e=this.currentSource(),t=[];return 0!==Object.keys(e).length&&t.push(e),this.cache_.sources||t},e.currentSource=function(){return this.cache_.source||{}},e.currentSrc=function(){return this.currentSource()&&this.currentSource().src||""},e.currentType=function(){return this.currentSource()&&this.currentSource().type||""},e.preload=function(e){return void 0!==e?(this.techCall_("setPreload",e),void(this.options_.preload=e)):this.techGet_("preload")},e.autoplay=function(e){if(void 0===e)return this.options_.autoplay||!1;var t;"string"==typeof e&&/(any|play|muted)/.test(e)||!0===e&&this.options_.normalizeAutoplay?(this.options_.autoplay=e,this.manualAutoplay_("string"==typeof e?e:"play"),t=!1):this.options_.autoplay=!!e,t="undefined"==typeof t?this.options_.autoplay:t,this.tech_&&this.techCall_("setAutoplay",t)},e.playsinline=function(e){return void 0!==e?(this.techCall_("setPlaysinline",e),this.options_.playsinline=e,this):this.techGet_("playsinline")},e.loop=function(e){return void 0!==e?(this.techCall_("setLoop",e),void(this.options_.loop=e)):this.techGet_("loop")},e.poster=function(e){if(void 0===e)return this.poster_;(e=e||"")!==this.poster_&&(this.poster_=e,this.techCall_("setPoster",e),this.isPosterFromTech_=!1,this.trigger("posterchange"))},e.handleTechPosterChange_=function(){var e;this.poster_&&!this.options_.techCanOverridePoster||!this.tech_||!this.tech_.poster||(e=this.tech_.poster()||"")!==this.poster_&&(this.poster_=e,this.isPosterFromTech_=!0,this.trigger("posterchange"))},e.controls=function(e){if(void 0===e)return!!this.controls_;this.controls_!==(e=!!e)&&(this.controls_=e,this.usingNativeControls()&&this.techCall_("setControls",e),this.controls_?(this.removeClass("vjs-controls-disabled"),this.addClass("vjs-controls-enabled"),this.trigger("controlsenabled"),this.usingNativeControls()||this.addTechControl
4715sListeners_()):(this.removeClass("vjs-controls-enabled"),this.addClass("vjs-controls-disabled"),this.trigger("controlsdisabled"),this.usingNativeControls()||this.removeTechControlsListeners_()))},e.usingNativeControls=function(e){if(void 0===e)return!!this.usingNativeControls_;this.usingNativeControls_!==(e=!!e)&&(this.usingNativeControls_=e,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))},e.error=function(t){var i=this;if(void 0===t)return this.error_||null;if(a("beforeerror").forEach(function(e){e=e(i,t);T(e)&&!Array.isArray(e)||"string"==typeof e||"number"==typeof e||null===e?t=e:i.log.error("please return a value that MediaError expects in beforeerror hooks")}),this.options_.suppressNotSupportedError&&t&&4===t.code){var e=function(){this.error(t)};return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],e),void this.one("loadstart",function(){this.off(["click","touchstart"],e)})}if(null===t)return this.error_=t,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new bt(t),this.addClass("vjs-error"),h.error("(CODE:"+this.error_.code+" "+bt.errorTypes[this.error_.code]+")",this.error_.message,this.error_),this.trigger("error"),a("error").forEach(function(e){return e(i,i.error_)})},e.reportUserActivity=function(e){this.userActivity_=!0},e.userActive=function(e){if(void 0===e)return this.userActive_;if((e=!!e)!==this.userActive_){if(this.userActive_=e,this.userActive_)return this.userActivity_=!0,this.removeClass("vjs-user-inactive"),this.addClass("vjs-user-active"),void this.trigger("useractive");this.tech_&&this.tech_.one("mousemove",function(e){e.stopPropagation(),e.preventDefault()}),this.userActivity_=!1,this.removeClass("vjs-user-active"),this.addClass("vjs-user-inactive"),this.trigger("userinactive")}},e.listenForUserActivity_=function(){var t,i,n,r=Ve(this,this.reportUserActivity),e=function(e){r(),this.clearInterval(t)};this.on("mousedown",function(){r(),this.clearInterval(t),t=this.setInterval(r,250)}),this.on("mousemove",function(e){e.screenX===i&&e.screenY===n||(i=e.screenX,n=e.screenY,r())}),this.on("mouseup",e),this.on("mouseleave",e);var a,e=this.getChild("controlBar");!e||q||A||(e.on("mouseenter",function(e){0!==this.player().options_.inactivityTimeout&&(this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout),this.player().options_.inactivityTimeout=0}),e.on("mouseleave",function(e){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout})),this.on("keydown",r),this.on("keyup",r),this.setInterval(function(){var e;this.userActivity_&&(this.userActivity_=!1,this.userActive(!0),this.clearTimeout(a),(e=this.options_.inactivityTimeout)<=0||(a=this.setTimeout(function(){this.userActivity_||this.userActive(!1)},e)))},250)},e.playbackRate=function(e){if(void 0===e)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",e)},e.defaultPlaybackRate=function(e){return void 0!==e?this.techCall_("setDefaultPlaybackRate",e):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1},e.isAudio=function(e){if(void 0===e)return!!this.isAudio_;this.isAudio_=!!e},e.addTextTrack=function(e,t,i){if(this.tech_)return this.tech_.addTextTrack(e,t,i)},e.addRemoteTextTrack=function(e,t){if(this.tech_)return this.tech_.addRemoteTextTrack(e,t)},e.removeRemoteTextTrack=function(e){var t=(t=(e=void 0===e?{}:e).track)||e;if(this.tech_)return this.tech_.removeRemoteTextTrack(t)},e.getVideoPlaybackQuality=function(){return this.techGet_("getVideoPlaybackQuality")},e.videoWidth=function(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0},e.videoHeight=function(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0},e.language=function(e){if(void 0===e)return this.language_;this.language_!==String(e).toLowerCase()&&(this.language_=String(e).toLowerCase(),it
vendor: 4,295 bytes, line 4715
4715(this)&&this.trigger("languagechange"))},e.languages=function(){return lt(o.prototype.options_.languages,this.languages_)},e.toJSON=function(){var e=lt(this.options_),t=e.tracks;e.tracks=[];for(var i=0;i<t.length;i++){var n=t[i];(n=lt(n)).player=void 0,e.tracks[i]=n}return e},e.createModal=function(e,t){var i=this;(t=t||{}).content=e||"";var n=new At(this,t);return this.addChild(n),n.on("dispose",function(){i.removeChild(n)}),n.open(),n},e.updateCurrentBreakpoint_=function(){if(this.responsive())for(var e=this.currentBreakpoint(),t=this.currentWidth(),i=0;i<Nn.length;i++){var n=Nn[i];if(t<=this.breakpoints_[n]){if(e===n)return;e&&this.removeClass(Un[e]),this.addClass(Un[n]),this.breakpoint_=n;break}}},e.removeCurrentBreakpoint_=function(){var e=this.currentBreakpointClass();this.breakpoint_="",e&&this.removeClass(e)},e.breakpoints=function(e){return void 0===e||(this.breakpoint_="",this.breakpoints_=b({},Bn,e),this.updateCurrentBreakpoint_()),b(this.breakpoints_)},e.responsive=function(e){return void 0===e?this.responsive_:(e=Boolean(e))!==this.responsive_?((this.responsive_=e)?(this.on("playerresize",this.boundUpdateCurrentBreakpoint_),this.updateCurrentBreakpoint_()):(this.off("playerresize",this.boundUpdateCurrentBreakpoint_),this.removeCurrentBreakpoint_()),e):void 0},e.currentBreakpoint=function(){return this.breakpoint_},e.currentBreakpointClass=function(){return Un[this.breakpoint_]||""},e.loadMedia=function(e,t){var i,n,r,a=this;e&&"object"==typeof e&&(this.reset(),this.cache_.media=lt(e),i=(r=this.cache_.media).artwork,n=r.poster,e=r.src,r=r.textTracks,!i&&n&&(this.cache_.media.artwork=[{src:n,type:$i(n)}]),e&&this.src(e),n&&this.poster(n),Array.isArray(r)&&r.forEach(function(e){return a.addRemoteTextTrack(e,!1)}),this.ready(t))},e.getMedia=function(){if(this.cache_.media)return lt(this.cache_.media);var e=this.poster(),t={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),function(e){return{kind:e.kind,label:e.label,language:e.language,src:e.src}})};return e&&(t.poster=e,t.artwork=[{src:t.poster,type:$i(t.poster)}]),t},o.getTagSettings=function(e){var t,i={sources:[],tracks:[]},n=ae(e),r=n["data-setup"];if(ee(e,"vjs-fill")&&(n.fill=!0),ee(e,"vjs-fluid")&&(n.fluid=!0),null!==r&&(r=(t=St(r||"{}"))[0],t=t[1],r&&h.error(r),b(n,t)),b(i,n),e.hasChildNodes())for(var a=e.childNodes,s=0,o=a.length;s<o;s++){var u=a[s],l=u.nodeName.toLowerCase();"source"===l?i.sources.push(ae(u)):"track"===l&&i.tracks.push(ae(u))}return i},e.flexNotSupported_=function(){var e=document.createElement("i");return!("flexBasis"in e.style||"webkitFlexBasis"in e.style||"mozFlexBasis"in e.style||"msFlexBasis"in e.style||"msFlexOrder"in e.style)},e.debug=function(e){if(void 0===e)return this.debugEnabled_;e?(this.trigger("debugon"),this.previousLogLevel_=this.log.level,this.log.level("debug"),this.debugEnabled_=!0):(this.trigger("debugoff"),this.log.level(this.previousLogLevel_),this.previousLogLevel_=void 0,this.debugEnabled_=!1)},e.playbackRates=function(e){if(void 0===e)return this.cache_.playbackRates;Array.isArray(e)&&e.every(function(e){return"number"==typeof e})&&(this.cache_.playbackRates=e,this.trigger("playbackrateschange"))},o}(pt);oi.names.forEach(function(e){var t=oi[e];Fn.prototype[t.getterName]=function(){return this.tech_?this.tech_[t.getterName]():(this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName])}}),Fn.prototype.crossorigin=Fn.prototype.crossOrigin,Fn.players={};k=window.navigator;Fn.prototype.options_={techOrder:ji.defaultTechOrder_,html5:{},inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:k&&(k.languages&&k.languages[0]||k.userLanguage||k.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",normalizeAutoplay:!1,fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1},["ended","seeking","seekable","networkState","readyState"].forEach(function(e){Fn.prototype[e]=function(){return this.techGet_(e)}}),Rn.forEach(function(e){Fn.prototype["handleTech"+ut(e)+"_"]=function(){return this.trigger(e)}}),pt.registerComponent("Player",Fn);
4715var jn=m(function(i){function n(e,t){return i.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(e,t)}i.exports=n});function Hn(e){return Qn.hasOwnProperty(e)}function qn(e){return Hn(e)?Qn[e]:void 0}function Vn(e,t,i){i=(i?"before":"")+"pluginsetup",e.trigger(i,t),e.trigger(i+":"+t.name,t)}function Wn(t,i){function n(){Vn(this,{name:t,plugin:i,instance:null},!0);var e=i.apply(this,arguments);return $n(this,t),Vn(this,{name:t,plugin:i,instance:e}),e}return Object.keys(i).forEach(function(e){n[e]=i[e]}),n}function Gn(r,a){return a.prototype.name=r,function(){Vn(this,{name:r,plugin:a,instance:null},!0);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=Xn(a,[this].concat(t));return this[r]=function(){return n},Vn(this,n.getEventHash()),n}}var zn=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}},Xn=m(function(n){function r(e,t,i){return zn()?n.exports=r=Reflect.construct:n.exports=r=function(e,t,i){var n=[null];n.push.apply(n,t);n=new(Function.bind.apply(e,n));return i&&jn(n,i.prototype),n},r.apply(null,arguments)}n.exports=r}),Kn="plugin",Yn="activePlugins_",Qn={},$n=function(e,t){e[Yn]=e[Yn]||{},e[Yn][t]=!0},Jn=function(){function i(e){if(this.constructor===i)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=e,this.log||(this.log=this.player.log.createLogger(this.name)),rt(this),delete this.trigger,st(this,this.constructor.defaultState),$n(e,this.name),this.dispose=this.dispose.bind(this),e.on("dispose",this.dispose)}var e=i.prototype;return e.version=function(){return this.constructor.VERSION},e.getEventHash=function(e){return(e=void 0===e?{}:e).name=this.name,e.plugin=this.constructor,e.instance=this,e},e.trigger=function(e,t){return je(this.eventBusEl_,e,this.getEventHash(t=void 0===t?{}:t))},e.handleStateChanged=function(e){},e.dispose=function(){var e=this.name,t=this.player;this.trigger("dispose"),this.off(),t.off("dispose",this.dispose),t[Yn][e]=!1,this.player=this.state=null,t[e]=Gn(e,Qn[e])},i.isBasic=function(e){e="string"==typeof e?qn(e):e;return"function"==typeof e&&!i.prototype.isPrototypeOf(e.prototype)},i.registerPlugin=function(e,t){if("string"!=typeof e)throw new Error('Illegal plugin name, "'+e+'", must be a string, was '+typeof e+".");if(Hn(e))h.warn('A plugin named "'+e+'" already exists. You may want to avoid re-registering plugins!');else if(Fn.prototype.hasOwnProperty(e))throw new Error('Illegal plugin name, "'+e+'", cannot share a name with an existing player method!');if("function"!=typeof t)throw new Error('Illegal plugin for "'+e+'", must be a function, was '+typeof t+".");return Qn[e]=t,e!==Kn&&(i.isBasic(t)?Fn.prototype[e]=Wn(e,t):Fn.prototype[e]=Gn(e,t)),t},i.deregisterPlugin=function(e){if(e===Kn)throw new Error("Cannot de-register base plugin.");Hn(e)&&(delete Qn[e],delete Fn.prototype[e])},i.getPlugins=function(e){var i;return(e=void 0===e?Object.keys(Qn):e).forEach(function(e){var t=qn(e);t&&((i=i||{})[e]=t)}),i},i.getPluginVersion=function(e){e=qn(e);return e&&e.VERSION||""},i}();Jn.getPlugin=qn,Jn.BASE_PLUGIN_NAME=Kn,Jn.registerPlugin(Kn,Jn),Fn.prototype.usingPlugin=function(e){return!!this[Yn]&&!0===this[Yn][e]},Fn.prototype.hasPlugin=function(e){return!!Hn(e)};var Zn=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&jn(e,t)},er=function(e){return 0===e.indexOf("#")?e.slice(1):e};function tr(e,t,i){if(r=tr.getPlayer(e))return t&&h.warn('Player "'+e+'" is already initialised. Options will not be applied.'),i&&r.ready(i),r;var n="string"==typeof e?Te("#"+er(e)):e;if(!K(n))throw new TypeError("The element or ID supplied is not valid. (videojs)");n.ownerDocument.defaultView&&n.ownerDocument.body.contains(n)||h.warn("The element supplied is not included in the DOM"),t=t||{},a("beforesetup").forEach(function(e){e=e(n,lt(t));
4715T(e)&&!Array.isArray(e)?t=lt(t,e):h.error("please return an object in beforesetup hooks")});var r=new(pt.getComponent("Player"))(n,t,i);return a("setup").forEach(function(e){return e(r)}),r}tr.hooks_=i,tr.hooks=a,tr.hook=function(e,t){a(e,t)},tr.hookOnce=function(i,e){a(i,[].concat(e).map(function(t){return function e(){return n(i,e),t.apply(void 0,arguments)}}))},tr.removeHook=n,!0!==window.VIDEOJS_NO_DYNAMIC_STYLE&&X()&&((ar=Te(".vjs-styles-defaults"))||(ar=xe("vjs-styles-defaults"),(k=Te("head"))&&k.insertBefore(ar,k.firstChild),Ae(ar,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n "))),Ce(1,tr),tr.VERSION=u,tr.options=Fn.prototype.options_,tr.getPlayers=function(){return Fn.players},tr.getPlayer=function(e){var t=Fn.players;if("string"==typeof e){var i=er(e),n=t[i];if(n)return n;i=Te("#"+i)}else i=e;if(K(i)){e=i.player,i=i.playerId;if(e||t[i])return e||t[i]}},tr.getAllPlayers=function(){return Object.keys(Fn.players).map(function(e){return Fn.players[e]}).filter(Boolean)},tr.players=Fn.players,tr.getComponent=pt.getComponent,tr.registerComponent=function(e,t){ji.isTech(t)&&h.warn("The "+e+" tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)"),pt.registerComponent.call(pt,e,t)},tr.getTech=ji.getTech,tr.registerTech=ji.registerTech,tr.use=function(e,t){Hi[e]=Hi[e]||[],Hi[e].push(t)},Object.defineProperty(tr,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(tr.middleware,"TERMINATOR",{value:Vi,writeable:!1,enumerable:!0}),tr.browser=W,tr.TOUCH_ENABLED=F,tr.extend=function(e,t){var i,n=function(){e.apply(this,arguments)},r={};for(i in"object"==typeof(t=void 0===t?{}:t)?(t.constructor!==Object.prototype.constructor&&(n=t.constructor),r=t):"function"==typeof t&&(n=t),Zn(n,e),e&&(n.super_=e),r)r.hasOwnProperty(i)&&(n.prototype[i]=r[i]);return n},tr.mergeOptions=lt,tr.bind=Ve,tr.registerPlugin=Jn.registerPlugin,tr.deregisterPlugin=Jn.deregisterPlugin,tr.plugin=function(e,t){return h.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),Jn.registerPlugin(e,t)},tr.getPlugins=Jn.getPlugins,tr.getPlugin=Jn.getPlugin,tr.getPluginVersion=Jn.getPluginVersion,tr.addLanguage=function(e,t){var i;return e=(""+e).toLowerCase(),tr.options.languages=lt(tr.options.languages,((i={})[e]=t,i)),tr.options.languages[e]},tr.log=h,tr.createLogger=p,tr.createTimeRange=tr.createTimeRanges=vt,tr.formatTime=ln,tr.setFormatTime=function(e){un=e},tr.resetFormatTime=function(){un=on},tr.parseUrl=Rt,tr.isCrossOrigin=Ut,tr.EventTarget=ze,tr.on=Be,tr.one=He,tr.off=Fe,tr.trigger=je,tr.xhr=Jt,tr.TextTrack=ri,tr.AudioTrack=x,tr.VideoTrack=U,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach(function(e){tr[e]=function(){return h.warn("videojs."+e+"() is deprecated; use videojs.dom."+e+"() instead"),we[e].apply(null,arguments)}}),tr.computedStyle=w,tr.dom=we,tr.url=zt,tr.defineLazyProperty=An,tr.addLanguage("en",{"Non-Fullscreen":"Exit Fullscreen"});function ir(e,t){if(/^[a-z]+:/i.test(t))return t;/^data:/.test(e)&&(e=window.location&&window.location.href||"");var i="function"==typeof window.URL,n=/^\/\//.test(e),r=!window.location&&!/\/\//i.test(e);if(i?e=new window.URL(e,window.location||rr):/\/\//i.test(e)||(e=nr.buildAbsoluteURL(window.location&&window.location.href||"",e)),i){i=new URL(t,e);return r?i.href.slice(rr.length):n?i.href.slice(i.protocol.length):i.href}return nr.buildAbsoluteURL(e,t)}var nr=m(function(e,t){var i,a,n,r,s;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#[^]*)?$/,a=/^([^\/?#]*)([^]*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,s={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=s.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=s.normalizePath(n.path),s.buildURLFromParts(n)}n=s.parseURL(t);if(!n)throw new Error("Error trying to parse relative URL.");
4715if(n.scheme)return i.alwaysNormalize?(n.path=s.normalizePath(n.path),s.buildURLFromParts(n)):t;t=s.parseURL(e);if(!t)throw new Error("Error trying to parse base URL.");!t.netLoc&&t.path&&"/"!==t.path[0]&&(r=a.exec(t.path),t.netLoc=r[1],t.path=r[2]),t.netLoc&&!t.path&&(t.path="/");var r,e={scheme:t.scheme,netLoc:n.netLoc,path:null,params:n.params,query:n.query,fragment:n.fragment};return n.netLoc||(e.netLoc=t.netLoc,"/"!==n.path[0]&&(n.path?(r=(r=t.path).substring(0,r.lastIndexOf("/")+1)+n.path,e.path=s.normalizePath(r)):(e.path=t.path,n.params||(e.params=t.params,n.query||(e.query=t.query))))),null===e.path&&(e.path=i.alwaysNormalize?s.normalizePath(n.path):n.path),s.buildURLFromParts(e)},parseURL:function(e){e=i.exec(e);return e?{scheme:e[1]||"",netLoc:e[2]||"",path:e[3]||"",params:e[4]||"",query:e[5]||"",fragment:e[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=s}),rr="http://example.com",ar=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;t=this.listeners[e].indexOf(t);return this.listeners[e]=this.listeners[e].slice(0),this.listeners[e].splice(t,1),-1<t},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n<i;++n)t[n].call(this,arguments[1]);else for(var r=Array.prototype.slice.call(arguments,1),a=t.length,s=0;s<a;++s)t[s].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}(),sr=function(e){return window.atob?window.atob(e):Buffer.from(e,"base64").toString("binary")};function or(e){for(var t=sr(e),i=new Uint8Array(t.length),n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i} 4716 /*! @name m3u8-parser @version 4.7.0 @license Apache-2.0 */function ur(e){var t=/([0-9.]*)?@?([0-9.]*)?/.exec(e||""),e={};return t[1]&&(e.length=parseInt(t[1],10)),t[2]&&(e.offset=parseInt(t[2],10)),e}function lr(e){for(var t,i=e.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),n={},r=i.length;r--;)""!==i[r]&&((t=/([^=]*)=(.*)/.exec(i[r]).slice(1))[0]=t[0].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^['"](.*)['"]$/g,"$1"),n[t[0]]=t[1]);return n}function cr(t){var i={};return Object.keys(t).forEach(function(e){i[e.toLowerCase().replace(/-(\w)/g,function(e){return e[1].toUpperCase()})]=t[e]}),i}function dr(e){var t,i,n,r,a=e.serverControl,s=e.targetDuration,o=e.partTargetDuration;a&&(t="#EXT-X-SERVER-CONTROL",i="holdBack",n="partHoldBack",r=s&&3*s,e=o&&2*o,s&&!a.hasOwnProperty(i)&&(a[i]=r,this.trigger("info",{message:t+" defaulting HOLD-BACK to targetDuration * 3 ("+r+")."})),r&&a[i]<r&&(this.trigger("warn",{message:t+" clamping HOLD-BACK ("+a[i]+") to targetDuration * 3 ("+r+")"}),a[i]=r),o&&!a.hasOwnProperty(n)&&(a[n]=3*o,this.trigger("info",{message:t+" defaulting PART-HOLD-BACK to partTargetDuration * 3 ("+a[n]+")."})),o&&a[n]<e&&(this.trigger("warn",{message:t+" clamping PART-HOLD-BACK ("+a[n]+") to partTargetDuration * 2 ("+e+")."}),a[n]=e))}function hr(e){return e&&e.replace(/avc1\.(\d+)\.(\d+)/i,function(e,t,i){return"avc1."+("00"+Number(t).toString(16)).slice(-2)+"00"+("00"+Number(i).toString(16)).slice(-2)})}function pr(e){var e=(e=void 0===e?"":e).split(","),a=[];return e.forEach(function(n){var r;n=n.trim(),Er.forEach(function(e){var t,i=wr[e].exec(n.toLowerCase());!i||i.length<=1||(r=e,t=n.substring(0,i[1].length),i=n.replace(t,""),a.push({type:t,details:i,mediaType:e}))}),r||a.push({type:n,details:"",mediaType:"unknown"})}),a}function fr(e){return wr.audio.test((e=void 0===e?"":e).trim().toLowerCase())}function mr(e){if(e&&"string"==typeof e){var t=e.toLowerCase().split(",").map(function(e){return hr(e.trim())}),i="video";1===t.length&&fr(t[0])?i="audio":1===t.length&&(n=t[0],wr.text.test((n=void 0===n?"":n).trim().toLowerCase()))&&
4716(i="application");var n="mp4";return t.every(function(e){return wr.mp4.test(e)})?n="mp4":t.every(function(e){return wr.webm.test(e)})?n="webm":t.every(function(e){return wr.ogg.test(e)})&&(n="ogg"),i+"/"+n+';codecs="'+e+'"'}}function gr(e){return void 0===e&&(e=""),window.MediaSource&&window.MediaSource.isTypeSupported&&window.MediaSource.isTypeSupported(mr(e))||!1}function yr(e){return(e=void 0===e?"":e).toLowerCase().split(",").every(function(e){e=e.trim();for(var t=0;t<kr.length;t++)if(wr["muxer"+kr[t]].test(e))return!0;return!1})}function vr(e){return Ir.test(e)?"hls":xr.test(e)?"dash":"application/vnd.videojs.vhs+json"===e?"vhs-json":null}var _r=function(t){function e(){var e=t.call(this)||this;return e.buffer="",e}return mt(e,t),e.prototype.push=function(e){var t;for(this.buffer+=e,t=this.buffer.indexOf("\n");-1<t;t=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,t)),this.buffer=this.buffer.substring(t+1)},e}(ar),br=String.fromCharCode(9),Tr=function(t){function e(){var e=t.call(this)||this;return e.customParsers=[],e.tagMappers=[],e}mt(e,t);var i=e.prototype;return i.push=function(i){var r,a,s=this;0!==(i=i.trim()).length&&("#"===i[0]?this.tagMappers.reduce(function(e,t){t=t(i);return t===i?e:e.concat([t])},[i]).forEach(function(e){for(var t,i,n=0;n<s.customParsers.length;n++)if(s.customParsers[n].call(s,e))return;if(0===e.indexOf("#EXT"))if(e=e.replace("\r",""),r=/^#EXTM3U/.exec(e))s.trigger("data",{type:"tag",tagType:"m3u"});else{if(r=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(e))return a={type:"tag",tagType:"inf"},r[1]&&(a.duration=parseFloat(r[1])),r[2]&&(a.title=r[2]),void s.trigger("data",a);if(r=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(e))return a={type:"tag",tagType:"targetduration"},r[1]&&(a.duration=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(e))return a={type:"tag",tagType:"version"},r[1]&&(a.version=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return a={type:"tag",tagType:"media-sequence"},r[1]&&(a.number=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return a={type:"tag",tagType:"discontinuity-sequence"},r[1]&&(a.number=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(e))return a={type:"tag",tagType:"playlist-type"},r[1]&&(a.playlistType=r[1]),void s.trigger("data",a);if(r=/^#EXT-X-BYTERANGE:?(.*)?$/.exec(e))return a=g(ur(r[1]),{type:"tag",tagType:"byterange"}),void s.trigger("data",a);if(r=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(e))return a={type:"tag",tagType:"allow-cache"},r[1]&&(a.allowed=!/NO/.test(r[1])),void s.trigger("data",a);if(r=/^#EXT-X-MAP:?(.*)$/.exec(e))return a={type:"tag",tagType:"map"},r[1]&&((t=lr(r[1])).URI&&(a.uri=t.URI),t.BYTERANGE&&(a.byterange=ur(t.BYTERANGE))),void s.trigger("data",a);if(r=/^#EXT-X-STREAM-INF:?(.*)$/.exec(e))return a={type:"tag",tagType:"stream-inf"},r[1]&&(a.attributes=lr(r[1]),a.attributes.RESOLUTION&&(i={},(t=a.attributes.RESOLUTION.split("x"))[0]&&(i.width=parseInt(t[0],10)),t[1]&&(i.height=parseInt(t[1],10)),a.attributes.RESOLUTION=i),a.attributes.BANDWIDTH&&(a.attributes.BANDWIDTH=parseInt(a.attributes.BANDWIDTH,10)),a.attributes["PROGRAM-ID"]&&(a.attributes["PROGRAM-ID"]=parseInt(a.attributes["PROGRAM-ID"],10))),void s.trigger("data",a);if(r=/^#EXT-X-MEDIA:?(.*)$/.exec(e))return a={type:"tag",tagType:"media"},r[1]&&(a.attributes=lr(r[1])),void s.trigger("data",a);if(r=/^#EXT-X-ENDLIST/.exec(e))s.trigger("data",{type:"tag",tagType:"endlist"});else{if(!(r=/^#EXT-X-DISCONTINUITY/.exec(e)))return(r=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(e))?(a={type:"tag",tagType:"program-date-time"},r[1]&&(a.dateTimeString=r[1],a.dateTimeObject=new Date(r[1])),void s.trigger("data",a)):(r=/^#EXT-X-KEY:?(.*)$/.exec(e))?(a={type:"tag",tagType:"key"},r[1]&&(a.attributes=lr(r[1]),a.attributes.IV&&("0x"===a.attributes.IV.substring(0,2).toLowerCase()&&(a.attributes.IV=a.attributes.IV.substring(2)),a.attributes.IV=a.attributes.IV.match(/.{8}/g),a.attributes.IV[0]=parseInt(a.attributes.IV[0],16),a.attributes.IV[1]=parseInt(a.attributes.IV[1],16),a.attributes.IV[2]=parseInt(a.attributes.IV[2],16),a.attributes.IV[3]=parseInt(a.attributes.IV[3],16),a.attributes.IV=new Uint32Array(a.attributes.IV))),void s.trigger("data",a)):(r=/^#EXT-X-START:?(.*)$/.exec(e))?(a={type:"tag",tagType:"start"},r[1]&&(a.attributes=lr(r[1]),a.attributes["TIME-OFFSET"]=parseFloat(a.attributes["TIME-OFFSET"]),a.attributes.PRECISE=/YES/.test(a.attributes.PRECISE)),void s.trigger("data",a)):(r=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-out-cont"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-out"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-CUE-IN:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-in"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-SKIP:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"skip"}).attributes=lr(r[1]),a.attributes.hasOwnProperty("SKIPPED-SEGMENTS")&&(a.attributes["SKIPPED-SEGMENTS"]=parseInt(a.attributes["SKIPPED-SEGMENTS"],10)),a.attributes.hasOwnProperty("RECENTLY-REMOVED-DATERANGES")&&(a.attributes["RECENTLY-REMOVED-DATERANGES"]=a.attributes["RECENTLY-REMOVED-DATERANGES"].split(br)),void s.trigger("data",a)):(r=/^#EXT-X-PART
4716:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"part"}).attributes=lr(r[1]),["DURATION"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),["INDEPENDENT","GAP"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=/YES/.test(a.attributes[e]))}),a.attributes.hasOwnProperty("BYTERANGE")&&(a.attributes.byterange=ur(a.attributes.BYTERANGE)),void s.trigger("data",a)):(r=/^#EXT-X-SERVER-CONTROL:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"server-control"}).attributes=lr(r[1]),["CAN-SKIP-UNTIL","PART-HOLD-BACK","HOLD-BACK"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),["CAN-SKIP-DATERANGES","CAN-BLOCK-RELOAD"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=/YES/.test(a.attributes[e]))}),void s.trigger("data",a)):(r=/^#EXT-X-PART-INF:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"part-inf"}).attributes=lr(r[1]),["PART-TARGET"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),void s.trigger("data",a)):(r=/^#EXT-X-PRELOAD-HINT:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"preload-hint"}).attributes=lr(r[1]),["BYTERANGE-START","BYTERANGE-LENGTH"].forEach(function(e){var t;a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseInt(a.attributes[e],10),t="BYTERANGE-LENGTH"===e?"length":"offset",a.attributes.byterange=a.attributes.byterange||{},a.attributes.byterange[t]=a.attributes[e],delete a.attributes[e])}),void s.trigger("data",a)):(r=/^#EXT-X-RENDITION-REPORT:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"rendition-report"}).attributes=lr(r[1]),["LAST-MSN","LAST-PART"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseInt(a.attributes[e],10))}),void s.trigger("data",a)):void s.trigger("data",{type:"tag",data:e.slice(4)});s.trigger("data",{type:"tag",tagType:"discontinuity"})}}else s.trigger("data",{type:"comment",text:e.slice(1)})}):this.trigger("data",{type:"uri",uri:i}))},i.addParser=function(e){var t=this,i=e.expression,n=e.customType,r=e.dataParser,a=e.segment;"function"!=typeof r&&(r=function(e){return e}),this.customParsers.push(function(e){if(i.exec(e))return t.trigger("data",{type:"custom",data:r(e),customType:n,segment:a}),!0})},i.addTagMapper=function(e){var t=e.expression,i=e.map;this.tagMappers.push(function(e){return t.test(e)?i(e):e})},e}(ar),Sr=function(t){function e(){var e=t.call(this)||this;e.lineStream=new _r,e.parseStream=new Tr,e.lineStream.pipe(e.parseStream);var n,r,a=ft(e),o=[],u={},l=!1,c={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},d=0;e.manifest={allowCache:!0,discontinuityStarts:[],segments:[]};var h=0,p=0;return e.on("end",function(){u.uri||!u.parts&&!u.preloadHints||(!u.map&&n&&(u.map=n),!u.key&&r&&(u.key=r),u.timeline||"number"!=typeof d||(u.timeline=d),e.manifest.preloadSegment=u)}),e.parseStream.on("data",function(s){var t,i;({tag:function(){({version:function(){s.version&&(this.manifest.version=s.version)},"allow-cache":function(){this.manifest.allowCache=s.allowed,"allowed"in s||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange:function(){var e={};"length"in s&&((u.byterange=e).length=s.length,"offset"in s||(s.offset=h)),"offset"in s&&((u.byterange=e).offset=s.offset),h=e.offset+e.length},endlist:function(){this.manifest.endList=!0},inf:function(){"mediaSequence"in this.manifest||(this.manifest.mediaSequence=0,this.trigger("info",{message:"defaulting media sequence to zero"})),"discontinuitySequence"in this.manifest||(this.manifest.discontinuitySequence=0,this.trigger("info",{message:"defaulting discontinuity sequence to zero"})),0<s.duration&&(u.duration=s.duration),0===s.duration&&(u.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=o},key:function(){if(s.attributes)if("NONE"!==s.attributes.METHOD)if(s.attributes.URI){if("com.apple.streamingkeydelivery"===s.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:s.attributes});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===s.attributes.KEYFORMAT)return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(s.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===s.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==s.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):s.attributes.KEYID&&"0x"===s.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:s.attributes.KEYFORMAT,keyId:s.attributes.KEYID.substring(2)},pssh:or(s.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}));s.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),r={method:s.attributes.METHOD||"AES-128",uri:s.attributes.URI},"undefined"!=typeof s.attributes.IV&&(r.iv=s.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else r=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence":function(){isFinite(s.number)?this.manifest.mediaSequence=s.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+s.number})},"discontinuity-sequence":function(){isFinite(s.number)?(this.manifest.discontinuitySequence=s.number,d=s.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+s.number})},"playlist-type":function(){/VOD|EVENT/.test(s.playlistType)?this.manifest.playlistType=s.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+s.playlist})},map:function(){n={},s.uri&&(n.uri=s.uri),s.byterange&&(n.byterange=s.byterange),r&&(n.key=r)},"stream-inf":function(){this.manifest.playlists=o,this.manifest.mediaGroups=this.manifest.mediaGroups||c,s.attributes?(u.attributes||(u.attributes={}),g(u.attributes,s.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media:function(){var e;this.manifest.mediaGroups=this.manifest.mediaGroups||c,s.attributes&&s.attributes.TYPE&&s.attributes["GROUP-ID"]&&s.attributes.NAME?((e=this.manifest.mediaGroups[s.attributes.TYPE])[s.attributes["GROUP-ID"]]=e[s.attributes["GROUP-ID"]]||{},t=e[s.attributes["GROUP-ID"]],(i={default:/yes/i.test(s.attributes.DEFAULT)}).default?i.autoselect=!0:i.autoselect=/yes/i.test(s.attributes.AUTOSELECT),s.attributes.LANGUAGE&&(i.language=s.attributes.LANGUAGE),s.attributes.URI&&(i.uri=s.attributes.URI),s.attributes["INSTREAM-ID"]&&(i.instreamId=s.attributes["INSTREAM-ID"]),s.attributes.CHARACTERISTICS&&(i.characteristics=s.attributes.CHARACTERISTICS),s.attributes.FORCED&&(i.forced=/yes/i.test(s.attributes.FORCED)),t[s.attributes.NAME]=i):this.trigger("warn",{message:"ignoring incomplete or missing media group"})},discontinuity:function(){d+=1,u.discontinuity=!0,this.manifest.discontinuityStarts.push(o.length)},"program-date-time":function(){"undefined"==typeof this.manifest.dateTimeString&&(this.manifest.dateTimeString=s.dateTimeString,this.manifest.dateTimeObject=s.dateTimeObject),u.dateTimeString=s.dateTimeString,u.dateTimeObject=s.dateTimeObject},targetduration:function(){!isFinite(s.duration)||s.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+s.duration}):(this.manifest.targetDuration=s.duration,dr.call(this,this.manifest))},start:function(){s.attributes&&!isNaN(s.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:s.attributes["TIME-OFFSET"],precise:s.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out":function(){u.cueOut=s.data},"cue-out-cont":function(){u.cueOutCont=s.data},"cue-in":function(){u.cueIn=s.data},skip:function(){this.manifest.skip=cr(s.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",s.attributes,["SKIPPED-SEGMENTS"])},part:function(){var i=this;l=!0;var e=this.manifest.segments.length,t=cr(s.attributes);u.parts=u.parts||[],u.parts.push(t),t.byterange&&(t.byterange.hasOwnProperty("offset")||(t.byterange.offset=p),p=t.byterange.offset+t.byterange.length);var n=u.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #"+n+" for segment #"+e,s.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEac
4716h(function(e,t){e.hasOwnProperty("lastPart")||i.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #"+t+" lacks required attribute(s): LAST-PART"})})},"server-control":function(){var e=this.manifest.serverControl=cr(s.attributes);e.hasOwnProperty("canBlockReload")||(e.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),dr.call(this,this.manifest),e.canSkipDateranges&&!e.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"})},"preload-hint":function(){var e=this.manifest.segments.length,t=cr(s.attributes),i=t.type&&"PART"===t.type;u.preloadHints=u.preloadHints||[],u.preloadHints.push(t),t.byterange&&(t.byterange.hasOwnProperty("offset")||(t.byterange.offset=i?p:0,i&&(p=t.byterange.offset+t.byterange.length)));var n=u.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #"+n+" for segment #"+e,s.attributes,["TYPE","URI"]),t.type)for(var r=0;r<u.preloadHints.length-1;r++){var a=u.preloadHints[r];a.type&&a.type===t.type&&this.trigger("warn",{message:"#EXT-X-PRELOAD-HINT #"+n+" for segment #"+e+" has the same TYPE "+t.type+" as preload hint #"+r})}},"rendition-report":function(){var e=cr(s.attributes);this.manifest.renditionReports=this.manifest.renditionReports||[],this.manifest.renditionReports.push(e);var t=this.manifest.renditionReports.length-1,e=["LAST-MSN","URI"];l&&e.push("LAST-PART"),this.warnOnMissingAttributes_("#EXT-X-RENDITION-REPORT #"+t,s.attributes,e)},"part-inf":function(){this.manifest.partInf=cr(s.attributes),this.warnOnMissingAttributes_("#EXT-X-PART-INF",s.attributes,["PART-TARGET"]),this.manifest.partInf.partTarget&&(this.manifest.partTargetDuration=this.manifest.partInf.partTarget),dr.call(this,this.manifest)}}[s.tagType]||function(){}).call(a)},uri:function(){u.uri=s.uri,o.push(u),!this.manifest.targetDuration||"duration"in u||(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),u.duration=this.manifest.targetDuration),r&&(u.key=r),u.timeline=d,n&&(u.map=n),p=0,u={}},comment:function(){},custom:function(){s.segment?(u.custom=u.custom||{},u.custom[s.customType]=s.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[s.customType]=s.data)}})[s.type].call(a)}),e}mt(e,t);var i=e.prototype;return i.warnOnMissingAttributes_=function(e,t,i){var n=[];i.forEach(function(e){t.hasOwnProperty(e)||n.push(e)}),n.length&&this.trigger("warn",{message:e+" lacks required attribute(s): "+n.join(", ")})},i.push=function(e){this.lineStream.push(e)},i.end=function(){this.lineStream.push("\n"),this.trigger("end")},i.addParser=function(e){this.parseStream.addParser(e)},i.addTagMapper=function(e){this.parseStream.addTagMapper(e)},e}(ar),wr={mp4:/^(av0?1|avc0?[1234]|vp0?9|flac|opus|mp3|mp4a|mp4v|stpp.ttml.im1t)/,webm:/^(vp0?[89]|av0?1|opus|vorbis)/,ogg:/^(vp0?[89]|theora|flac|opus|vorbis)/,video:/^(av0?1|avc0?[1234]|vp0?[89]|hvc1|hev1|theora|mp4v)/,audio:/^(mp4a|flac|vorbis|opus|ac-[34]|ec-3|alac|mp3|speex|aac)/,text:/^(stpp.ttml.im1t)/,muxerVideo:/^(avc0?1)/,muxerAudio:/^(mp4a)/,muxerText:/a^/},Er=["video","audio","text"],kr=["Video","Audio","Text"],Cr="mp4a.40.2",Ir=/^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i,xr=/^application\/dash\+xml/i;function Ar(e,t){return(t=void 0===t?Object:t)&&"function"==typeof t.freeze?t.freeze(e):e}var Pr=Ar({HTML:"text/html",isHTML:function(e){return e===Pr.HTML},XML_APPLICATION:"application/xml",XML_TEXT:"text/xml",XML_XHTML_APPLICATION:"application/xhtml+xml",XML_SVG_IMAGE:"image/svg+xml"}),Lr=Ar({HTML:"http://www.w3.org/1999/xhtml",isHTML:function(e){return e===Lr.HTML},SVG:"http://www.w3.org/2000/svg",XML:"http://www.w3.org/XML/1998/namespace",XMLNS:"http://www.w3.org/2000/xmlns/"}),Dr={freeze:Ar,MIME_TYPE:Pr,NAMESPACE:Lr},Or=Dr.NAMESPACE;function Rr(e){return""!==e}function Mr(e,t){return e.hasOwnProperty(t)||(e[t]=!0),e}function Nr(e){if(!e)return[];e=(e=e)?e.split(/[\t\n\f\r ]+/).filter(Rr):[];return Object.keys(e.reduce(Mr,{}))}function Ur(e,t){for(var i in e)t[i]=e[i]}function Br(e,t){var i,n=e.prototype;n instanceof t||((i=function(){}).prototype=t.prototype,Ur(n,i=new i),e.prototype=n=i),n.constructor!=e&&(n.constructor=e)}var W={},Fr=W.ELEMENT_NODE=1,jr=W.ATTRIBUTE_NODE=2,Hr=W.TEXT_NODE=3,qr=W.CDATA_SECTION_NODE=4,Vr=W.ENTITY_REFERENCE_NODE=5,Wr=(W.ENTITY_NODE=6,W.PROCESSING_INSTRUCTION_NODE=7),Gr=W.COMMENT_NODE=8,zr=W.DOCUMENT_NODE=9,Xr=W.DOCUMENT_TYPE_NODE=10,Kr=W.DOCUMENT_FRAGMENT_NODE=11,x=(W.NOTATION_NODE=12,{}),Yr={};x.INDEX_SIZE_ERR=(Yr[1]="Index size error",1),x.DOMSTRING_SIZE_ERR=(Yr[2]="DOMString size error",2);x.HIERARCHY_REQUEST_ERR=(Yr[3]="Hierarchy request error",3);x.WRONG_DOCUMENT_ERR=(Yr[4]="Wrong document",4),x.INVALID_CHARACTER_ERR=(Yr[5]="Invalid character",5),x.NO_DATA_ALLOWED_ER
4716R=(Yr[6]="No data allowed",6),x.NO_MODIFICATION_ALLOWED_ERR=(Yr[7]="No modification allowed",7);x.NOT_FOUND_ERR=(Yr[8]="Not found",8);x.NOT_SUPPORTED_ERR=(Yr[9]="Not supported",9);var Qr;x.INUSE_ATTRIBUTE_ERR=(Yr[10]="Attribute in use",10);function $r(e,t){var i;return t instanceof Error?i=t:(i=this,Error.call(this,Yr[e]),this.message=Yr[e],Error.captureStackTrace&&Error.captureStackTrace(this,$r)),i.code=e,t&&(this.message=this.message+": "+t),i}function Jr(){}function Zr(e,t){this._node=e,this._refresh=t,ea(this)}function ea(e){var t,i=e._node._inc||e._node.ownerDocument._inc;e._inc!=i&&(t=e._refresh(e._node),La(e,"length",t.length),Ur(t,e),e._inc=i)}function ta(){}function ia(e,t){for(var i=e.length;i--;)if(e[i]===t)return i}function na(e,t,i,n){n?t[ia(t,n)]=i:t[t.length++]=i,!e||(t=(i.ownerElement=e).ownerDocument)&&(n&&ca(t,e,n),e=e,i=i,(t=t)&&t._inc++,i.namespaceURI===Or.XMLNS&&(e._nsMap[i.prefix?i.localName:""]=i.value))}function ra(e,t,i){var n=ia(t,i);if(!(0<=n))throw $r(8,new Error(e.tagName+"@"+i));for(var r,a=t.length-1;n<a;)t[n]=t[++n];t.length=a,!e||(r=e.ownerDocument)&&(ca(r,e,i),i.ownerElement=null)}function aa(){}function sa(){}function oa(e){return("<"==e?"<":">"==e&&">")||"&"==e&&"&"||'"'==e&&"""||"&#"+e.charCodeAt()+";"}function ua(e,t){if(t(e))return 1;if(e=e.firstChild)do{if(ua(e,t))return 1}while(e=e.nextSibling)}function la(){}function ca(e,t,i){e&&e._inc++,i.namespaceURI===Or.XMLNS&&delete t._nsMap[i.prefix?i.localName:""]}function da(e,t,i){if(e&&e._inc){e._inc++;var n=t.childNodes;if(i)n[n.length++]=i;else{for(var r=t.firstChild,a=0;r;)r=(n[a++]=r).nextSibling;n.length=a}}}function ha(e,t){var i=t.previousSibling,n=t.nextSibling;return i?i.nextSibling=n:e.firstChild=n,n?n.previousSibling=i:e.lastChild=i,da(e.ownerDocument,e),t}function pa(e,t,i){var n=t.parentNode;if(n&&n.removeChild(t),t.nodeType===Kr){var r=t.firstChild;if(null==r)return t;var a=t.lastChild}else r=a=t;n=i?i.previousSibling:e.lastChild;for(r.previousSibling=n,a.nextSibling=i,n?n.nextSibling=r:e.firstChild=r,null==i?e.lastChild=a:i.previousSibling=a;r.parentNode=e,r!==a&&(r=r.nextSibling););return da(e.ownerDocument||e,e),t.nodeType==Kr&&(t.firstChild=t.lastChild=null),t}function fa(){this._nsMap={}}function ma(){}function ga(){}function ya(){}function va(){}function _a(){}function ba(){}function Ta(){}function Sa(){}function wa(){}function Ea(){}function ka(){}function Ca(){}function Ia(e,t){var i,n=[],r=9==this.nodeType&&this.documentElement||this,a=r.prefix,s=r.namespaceURI;return Pa(this,n,e,t,i=s&&null==a&&null==(a=r.lookupPrefix(s))?[{namespace:s,prefix:null}]:i),n.join("")}function xa(e,t,i){var n=e.prefix||"",r=e.namespaceURI;if(r&&("xml"!==n||r!==Or.XML)&&r!==Or.XMLNS){for(var a=i.length;a--;){var s=i[a];if(s.prefix===n)return s.namespace!==r}return 1}}function Aa(e,t,i){e.push(" ",t,'="',i.replace(/[<&"]/g,oa),'"')}function Pa(e,t,i,n,r){if(r=r||[],n){if(!(e=n(e)))return;if("string"==typeof e)return void t.push(e)}switch(e.nodeType){case Fr:var a=e.attributes,s=a.length,o=e.firstChild,u=e.tagName,l=u;if(!(i=Or.isHTML(e.namespaceURI)||i)&&!e.prefix&&e.namespaceURI){for(var c,d=0;d<a.length;d++)if("xmlns"===a.item(d).name){c=a.item(d).value;break}if(!c)for(var h=r.length-1;0<=h;h--)if(""===(p=r[h]).prefix&&p.namespace===e.namespaceURI){c=p.namespace;break}if(c!==e.namespaceURI)for(var p,h=r.length-1;0<=h;h--)if((p=r[h]).namespace===e.namespaceURI){p.prefix&&(l=p.prefix+":"+u);break}}t.push("<",l);for(var f=0;f<s;f++)"xmlns"==(m=a.item(f)).prefix?r.push({prefix:m.localName,namespace:m.value}):"xmlns"==m.nodeName&&r.push({prefix:"",namespace:m.value});for(var m,g,y,f=0;f<s;f++)xa(m=a.item(f),0,r)&&(Aa(t,(g=m.prefix||"")?"xmlns:"+g:"xmlns",y=m.namespaceURI),r.push({prefix:g,namespace:y})),Pa(m,t,i,n,r);if(u===l&&xa(e,0,r)&&(Aa(t,(g=e.prefix||"")?"xmlns:"+g:"xmlns",y=e.namespaceURI),r.push({prefix:g,namespace:y})),o||i&&!/^(?:meta|link|img|br|hr|input)$/i.test(u)){if(t.push(">"),i&&/^script$/i.test(u))for(;o;)o.data?t.push(o.data):Pa(o,t,i,n,r.slice()),o=o.nextSibling;else for(;o;)Pa(o,t,i,n,r.slice()),o=o.nextSibling;t.push("</",l,">")}else t.push("/>");return;case zr:case Kr:for(o=e.firstChild;o;)Pa(o,t,i,n,r.slice()),o=o.nextSibling;return;
4716case jr:return Aa(t,e.name,e.value),0;case Hr:return t.push(e.data.replace(/[<&]/g,oa).replace(/]]>/g,"]]>"));case qr:return t.push("<![CDATA[",e.data,"]]>");case Gr:return t.push("\x3c!--",e.data,"--\x3e");case Xr:var v=e.publicId,_=e.systemId;return t.push("<!DOCTYPE ",e.name),void(v?(t.push(" PUBLIC ",v),_&&"."!=_&&t.push(" ",_),t.push(">")):_&&"."!=_?t.push(" SYSTEM ",_,">"):((_=e.internalSubset)&&t.push(" [",_,"]"),t.push(">")));case Wr:return t.push("<?",e.target," ",e.data,"?>");case Vr:return t.push("&",e.nodeName,";");default:t.push("??",e.nodeName)}}function La(e,t,i){e[t]=i}x.INVALID_STATE_ERR=(Yr[11]="Invalid state",11),x.SYNTAX_ERR=(Yr[12]="Syntax error",12),x.INVALID_MODIFICATION_ERR=(Yr[13]="Invalid modification",13),x.NAMESPACE_ERR=(Yr[14]="Invalid namespace",14),x.INVALID_ACCESS_ERR=(Yr[15]="Invalid access",15),$r.prototype=Error.prototype,Ur(x,$r),Jr.prototype={length:0,item:function(e){return this[e]||null},toString:function(e,t){for(var i=[],n=0;n<this.length;n++)Pa(this[n],i,e,t);return i.join("")}},Zr.prototype.item=function(e){return ea(this),this[e]},Br(Zr,Jr),ta.prototype={length:0,item:Jr.prototype.item,getNamedItem:function(e){for(var t=this.length;t--;){var i=this[t];if(i.nodeName==e)return i}},setNamedItem:function(e){var t=e.ownerElement;if(t&&t!=this._ownerElement)throw new $r(10);t=this.getNamedItem(e.nodeName);return na(this._ownerElement,this,e,t),t},setNamedItemNS:function(e){var t=e.ownerElement;if(t&&t!=this._ownerElement)throw new $r(10);return t=this.getNamedItemNS(e.namespaceURI,e.localName),na(this._ownerElement,this,e,t),t},removeNamedItem:function(e){e=this.getNamedItem(e);return ra(this._ownerElement,this,e),e},removeNamedItemNS:function(e,t){t=this.getNamedItemNS(e,t);return ra(this._ownerElement,this,t),t},getNamedItemNS:function(e,t){for(var i=this.length;i--;){var n=this[i];if(n.localName==t&&n.namespaceURI==e)return n}return null}},aa.prototype={hasFeature:function(e,t){return!0},createDocument:function(e,t,i){var n=new la;return n.implementation=this,n.childNodes=new Jr,n.doctype=i||null,i&&n.appendChild(i),t&&(t=n.createElementNS(e,t),n.appendChild(t)),n},createDocumentType:function(e,t,i){var n=new ba;return n.name=e,n.nodeName=e,n.publicId=t||"",n.systemId=i||"",n}},sa.prototype={firstChild:null,lastChild:null,previousSibling:null,nextSibling:null,attributes:null,parentNode:null,childNodes:null,ownerDocument:null,nodeValue:null,namespaceURI:null,prefix:null,localName:null,insertBefore:function(e,t){return pa(this,e,t)},replaceChild:function(e,t){this.insertBefore(e,t),t&&this.removeChild(t)},removeChild:function(e){return ha(this,e)},appendChild:function(e){return this.insertBefore(e,null)},hasChildNodes:function(){return null!=this.firstChild},cloneNode:function(e){return function e(t,i,n){var r=new i.constructor;for(var a in i){var s=i[a];"object"!=typeof s&&s!=r[a]&&(r[a]=s)}i.childNodes&&(r.childNodes=new Jr);r.ownerDocument=t;switch(r.nodeType){case Fr:var o=i.attributes,u=r.attributes=new ta,l=o.length;u._ownerElement=r;for(var c=0;c<l;c++)r.setAttributeNode(e(t,o.item(c),!0));break;case jr:n=!0}if(n)for(var d=i.firstChild;d;)r.appendChild(e(t,d,n)),d=d.nextSibling;return r}(this.ownerDocument||this,this,e)},normalize:function(){for(var e=this.firstChild;e;){var t=e.nextSibling;t&&t.nodeType==Hr&&e.nodeType==Hr?(this.removeChild(t),e.appendData(t.data)):(e.normalize(),e=t)}},isSupported:function(e,t){return this.ownerDocument.implementation.hasFeature(e,t)},hasAttributes:function(){return 0<this.attributes.length},lookupPrefix:function(e){for(var t=this;t;){var i=t._nsMap;if(i)for(var n in i)if(i[n]==e)return n;t=t.nodeType==jr?t.ownerDocument:t.parentNode}return null},lookupNamespaceURI:function(e){for(var t=this;t;){var i=t._nsMap;if(i&&e in i)return i[e];t=t.nodeType==jr?t.ownerDocument:t.parentNode}return null},isDefaultNamespace:function(e){return null==this.lookupPrefix(e)}},Ur(W,sa),Ur(W,sa.prototype),la.prototype={nodeName:"#document",nodeType:zr,doctype:null,documentElement:null,_inc:1,insertBefore:function(e,t){if(e.nodeType!=Kr)return null==this.documentElement&&e.nodeType==Fr&&(this.documentElement=e),pa(this,e,t),e.ownerDocument=this,e;for(var i=e.firstChild;i;){var n=i.nextSibling;this.insertBefore(i,t),i=n}return e},removeChild:function(e){return this.documentElement==e&&(this.documentElement=null),ha(this,e)},importNode:function(e,t){return function e(t,i,n){var r;switch(i.nodeType){case Fr:(r=i.cloneNode(!1)).ownerDocument=t;case Kr:break;case jr:n=!0}r=r||i.cloneNode(!1);r.ownerDocument=t;r.parentNode=null;if(n)for(var a=i.firstChild;a;)r.appendChild(e(t,a,n)),a=a.nextSibling;return r}(this,e,t)},getElementById:function(t){var i=null;return ua(this.documentElement,function(e){if(e.nodeType==Fr&&e.getAttribute("id")==t)return i=e,!0}),i},getElementsByClassName:function(s){var o=Nr(s);return new Zr(this,function(r){var a=[];return 0<o.length&&ua(r.documentElement,function(e){var t,i,n;e===r||e.nodeType!==Fr||(t=e.getAttribute("class"))&&((i=s===t)||(t=Nr(t),i=o.every((n=t,function(e){return n&&-1!==n.indexOf(e)}))),i&&a.push(e))}),a})},createElement:function(e){var t=new fa;return t.ownerDocument=this,t.nodeName=e,t.tagName=e,t.localName=e,t.childNodes=new Jr,(t.attributes=new ta)._ownerElement=t},createDocumentFragment:function(){var e=new Ea;return e.ownerDocument=this,e.childNodes=new Jr,e},createTextNode:function(e){var t=new ya;return t.ownerDocument=this,t.appendData(e),t},createComment:function(e){var t=new va;return t.ownerDocument=this,t.appendData(e),t},createCDATASection:function(e){var t=new _a;return t.ownerDocument=this,t.appendData(e),t},createProcessingInstruction:function(e,t){var i=new ka;return i.ownerDocument=this,i.tagName=i.target=e,i.nodeValue=i.data=t,i},createAttribute:function(e){var t=new ma;return t.ownerDocument=this,t.name=e,t.nodeName=e,t.localName=e,t.specified=!0,t},createEntityReference:function(e){var t=new wa;return t.ownerDocument=this,t.nodeName=e,t},createElementNS:function(e,t){var i=new fa,n=t.split(":"),r=i.attributes=new ta;return i.childNodes=new Jr,i.ownerDocument=this,i.nodeName=t,i.tagName=t,i.namespaceURI=e,2==n.length?(i.prefix=n[0],i.localName=n[1]):i.localName=t,r._ownerElement=i},createAttributeNS:function(e,t){var i=new ma,n=t.split(":");return i.ownerDocument=this,i.nodeName=t,i.name=t,i.namespaceURI=e,i.specified=!0,2==n.length?(i.prefix=n[0],i.localName=n[1]):i.localName=t,i}},Br(la,sa),la.prototype.getElementsByTagName=(fa.prototype={nodeType:Fr,hasAttribute:function(e){return null!=this.getAttributeNode(e)},getAttribute:function(e){e=this.getAttributeNode(e);return e&&e.value||""},getAttributeNode:function(e){return this.attributes.getNamedItem(e)},setAttribute:function(e,t){e=this.ownerDocument.createAttribute(e);e.value=e.nodeValue=""+t,this.setAttributeNode(e)},removeAttribute:function(e){e=this.getAttributeNode(e);e&&this.removeAttributeNode(e)}
4716,appendChild:function(e){return e.nodeType===Kr?this.insertBefore(e,null):function(e,t){var i=t.parentNode;i&&(n=e.lastChild,i.removeChild(t),n=e.lastChild);var n=e.lastChild;return t.parentNode=e,t.previousSibling=n,t.nextSibling=null,n?n.nextSibling=t:e.firstChild=t,e.lastChild=t,da(e.ownerDocument,e,t),t}(this,e)},setAttributeNode:function(e){return this.attributes.setNamedItem(e)},setAttributeNodeNS:function(e){return this.attributes.setNamedItemNS(e)},removeAttributeNode:function(e){return this.attributes.removeNamedItem(e.nodeName)},removeAttributeNS:function(e,t){t=this.getAttributeNodeNS(e,t);t&&this.removeAttributeNode(t)},hasAttributeNS:function(e,t){return null!=this.getAttributeNodeNS(e,t)},getAttributeNS:function(e,t){t=this.getAttributeNodeNS(e,t);return t&&t.value||""},setAttributeNS:function(e,t,i){t=this.ownerDocument.createAttributeNS(e,t);t.value=t.nodeValue=""+i,this.setAttributeNode(t)},getAttributeNodeNS:function(e,t){return this.attributes.getNamedItemNS(e,t)},getElementsByTagName:function(n){return new Zr(this,function(t){var i=[];return ua(t,function(e){e===t||e.nodeType!=Fr||"*"!==n&&e.tagName!=n||i.push(e)}),i})},getElementsByTagNameNS:function(n,r){return new Zr(this,function(t){var i=[];return ua(t,function(e){e===t||e.nodeType!==Fr||"*"!==n&&e.namespaceURI!==n||"*"!==r&&e.localName!=r||i.push(e)}),i})}}).getElementsByTagName,la.prototype.getElementsByTagNameNS=fa.prototype.getElementsByTagNameNS,Br(fa,sa),ma.prototype.nodeType=jr,Br(ma,sa),ga.prototype={data:"",substringData:function(e,t){return this.data.substring(e,e+t)},appendData:function(e){e=this.data+e,this.nodeValue=this.data=e,this.length=e.length},insertData:function(e,t){this.replaceData(e,0,t)},appendChild:function(e){throw new Error(Yr[3])},deleteData:function(e,t){this.replaceData(e,t,"")},replaceData:function(e,t,i){var n=this.data.substring(0,e),t=this.data.substring(e+t);this.nodeValue=this.data=i=n+i+t,this.length=i.length}},Br(ga,sa),ya.prototype={nodeName:"#text",nodeType:Hr,splitText:function(e){var t=(i=this.data).substring(e),i=i.substring(0,e);this.data=this.nodeValue=i,this.length=i.length;t=this.ownerDocument.createTextNode(t);return this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling),t}},Br(ya,ga),va.prototype={nodeName:"#comment",nodeType:Gr},Br(va,ga),_a.prototype={nodeName:"#cdata-section",nodeType:qr},Br(_a,ga),ba.prototype.nodeType=Xr,Br(ba,sa),Ta.prototype.nodeType=12,Br(Ta,sa),Sa.prototype.nodeType=6,Br(Sa,sa),wa.prototype.nodeType=Vr,Br(wa,sa),Ea.prototype.nodeName="#document-fragment",Ea.prototype.nodeType=Kr,Br(Ea,sa),ka.prototype.nodeType=Wr,Br(ka,sa),Ca.prototype.serializeToString=function(e,t,i){return Ia.call(e,t,i)},sa.prototype.toString=Ia;try{Object.defineProperty&&(Qr=function e(t){switch(t.nodeType){case Fr:case Kr:var i=[];for(t=t.firstChild;t;)7!==t.nodeType&&8!==t.nodeType&&i.push(e(t)),t=t.nextSibling;return i.join("");default:return t.nodeValue}},Object.defineProperty(Zr.prototype,"length",{get:function(){return ea(this),this.$$length}}),Object.defineProperty(sa.prototype,"textContent",{get:function(){return Qr(this)},set:function(e){switch(this.nodeType){case Fr:case Kr:for(;this.firstChild;)this.removeChild(this.firstChild);(e||String(e))&&this.appendChild(this.ownerDocument.createTextNode(e));break;default:this.data=e,this.value=e,this.nodeValue=e}}}),La=function(e,t,i){e["$$"+t]=i})}catch(e){}var U={DocumentType:ba,DOMException:$r,DOMImplementation:aa,Element:fa,Node:sa,NodeList:Jr,XMLSerializer:Ca},Da=m(function(e,t){var i=Dr.freeze;t.XML_ENTITIES=i({amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}),t.HTML_ENTITIES=i({lt:"<",gt:">",amp:"&",quot:'"',apos:"'",Agrave:"Ã",Aacute:"Ã",Acirc:"Ã",Atilde:"Ã",Auml:"Ã",Aring:"Ã
",AElig:"Ã",Ccedil:"Ã",Egrave:"Ã",Eacute:"Ã",Ecirc:"Ã",Euml:"Ã",Igrave:"Ã",Iacute:"Ã",Icirc:"Ã",Iuml:"Ã",ETH:"Ã",Ntilde:"Ã",Ograve:"Ã",Oacute:"Ã",Ocirc:"Ã",Otilde:"Ã",Ouml:"Ã",Oslash:"Ã",Ugrave:"Ã",Uacute:"Ã",Ucirc:"Ã",Uuml:"Ã",Yacute:"Ã",THORN:"Ã",szlig:"Ã",agrave:"à ",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"Ã¥",aelig:"æ",ccedil
vendor: 9,789 bytes, line 4716
4716:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"Ã",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",nbsp:" ",iexcl:"¡",cent:"¢",pound:"£",curren:"¤",yen:"Â¥",brvbar:"¦",sect:"§",uml:"¨",copy:"©",ordf:"ª",laquo:"«",not:"¬",shy:"ÂÂ",reg:"®",macr:"¯",deg:"°",plusmn:"±",sup2:"²",sup3:"³",acute:"´",micro:"µ",para:"¶",middot:"·",cedil:"¸",sup1:"¹",ordm:"º",raquo:"»",frac14:"¼",frac12:"½",frac34:"¾",iquest:"¿",times:"Ã",divide:"÷",forall:"â",part:"â",exist:"â",empty:"â
",nabla:"â",isin:"â",notin:"â",ni:"â",prod:"â",sum:"â",minus:"â",lowast:"â",radic:"â",prop:"â",infin:"â",ang:"â ",and:"â§",or:"â¨",cap:"â©",cup:"âª",int:"â«",there4:"â´",sim:"â¼",cong:"â
",asymp:"â",ne:"â ",equiv:"â¡",le:"â¤",ge:"â¥",sub:"â",sup:"â",nsub:"â",sube:"â",supe:"â",oplus:"â",otimes:"â",perp:"â¥",sdot:"â
",Alpha:"Î",Beta:"Î",Gamma:"Î",Delta:"Î",Epsilon:"Î",Zeta:"Î",Eta:"Î",Theta:"Î",Iota:"Î",Kappa:"Î",Lambda:"Î",Mu:"Î",Nu:"Î",Xi:"Î",Omicron:"Î",Pi:"Î ",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Î¥",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"Ï",rho:"Ï",sigmaf:"Ï",sigma:"Ï",tau:"Ï",upsilon:"Ï
",phi:"Ï",chi:"Ï",psi:"Ï",omega:"Ï",thetasym:"Ï",upsih:"Ï",piv:"Ï",OElig:"Å",oelig:"Å",Scaron:"Å ",scaron:"Å¡",Yuml:"Ÿ",fnof:"Æ",circ:"Ë",tilde:"Ë",ensp:"â",emsp:"â",thinsp:"â",zwnj:"â",zwj:"â",lrm:"â",rlm:"â",ndash:"â",mdash:"â",lsquo:"â",rsquo:"â",sbquo:"â",ldquo:"â",rdquo:"â",bdquo:"â",dagger:"â ",Dagger:"â¡",bull:"â¢",hellip:"â¦",permil:"â°",prime:"â²",Prime:"â³",lsaquo:"â¹",rsaquo:"âº",oline:"â¾",euro:"â¬",trade:"â¢",larr:"â",uarr:"â",rarr:"â",darr:"â",harr:"â",crarr:"âµ",lceil:"â",rceil:"â",lfloor:"â",rfloor:"â",loz:"â",spades:"â ",clubs:"â£",hearts:"â¥",diams:"â¦"}),t.entityMap=t.HTML_ENTITIES});Da.XML_ENTITIES,Da.HTML_ENTITIES,Da.entityMap;var Oa=Dr.NAMESPACE,zt=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,ar=new RegExp("[\\-\\.0-9"+zt.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"),Ra=new RegExp("^"+zt.source+ar.source+"*(?::"+zt.source+ar.source+"*)?$"),Ma=0,Na=1,Ua=2,Ba=3,Fa=4,ja=5,Ha=6,qa=7;function Va(e,t){this.message=e,this.locator=t,Error.captureStackTrace&&Error.captureStackTrace(this,Va)}function Wa(){}function Ga(e,t){return t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber,t}function za(e,t,i){for(var n=e.tagName,r=null,a=e.length;a--;){var s=e[a],o=s.qName,u=s.value,o=0<(c=o.indexOf(":"))?(l=s.prefix=o.slice(0,c),d=o.slice(c+1),"xmlns"===l&&d):(l=null,"xmlns"===(d=o)&&"");s.localName=d,!1!==o&&(null==r&&(r={},Xa(i,i={})),i[o]=r[o]=u,s.uri=Oa.XMLNS,t.startPrefixMapping(o,u))}for(var l,a=e.length;a--;)(l=(s=e[a]).prefix)&&("xml"===l&&(s.uri=Oa.XML),"xmlns"!==l&&(s.uri=i[l||""]));var c,d=0<(c=n.indexOf(":"))?(l=e.prefix=n.slice(0,c),e.localName=n.slice(c+1)):(l=null,e.localName=n),h=e.uri=i[l||""];if(t.startElement(h,d,n,e),!e.closed)return e.currentNSMap=i,e.localNSMap=r,1;if(t.endElement(h,d,n),r)for(l in r)t.endPrefixMapping(l)}function Xa(e,t){for(var i in e)t[i]=e[i]}function Ka(){this.attributeNames={}}(Va.prototype=new Error).name=Va.name,Wa.prototype={parse:function(e,t,i){var n=this.domBuilder;n.startDocument(),Xa(t,t={}),function(i,e,n,r,a){function s(e){var t=e.slice(1,-1);return t in n?n[t]:"#"===t.charAt(0)?65535<(t=parseInt(t.substr(1).replace("x","0x")))?(t-=65536,String.fromCharCode(55296+(t>>10),56320+(1023&t))):String.fromCharCode(t):(a.error("entity not found:"+e),e)}function t(e){var t;f<e&&(t=i.substring(f,e).replace(/&#?\w+;/g,s),d&&o(f),r.characters(t,0,e-f),f=e)}function o(e,t){for(;l<=e&&(t=c.exec(i));)u=t.index,l=u+t[0].length,d.lineNumber++;d.columnNumber=e-u+1}var u=0,l=0,c=/.*(?:\r\n?|\n)|.*$/g,d=r.locator,h=[{currentNSMap:e}],p={},f=0;for(;;){try{var m,g,y=i.indexOf("<",f);if(y<0)return i.substr(f).match(/^\s*$/)||(m=r.doc,g=m.createTextNode(i.substr(f)),m.appendChild(g),r.currentElement=g);switch(f<y&&t(y),i.charAt(y+1)){case"/":var v=i.indexOf(">",y+3),_=i.substring(y+2,v).replace(/[ \t\n\r]+$/g,""),b=h.pop();v<0?(_=i.substring(y+2).replace(/[\s<].*/,""),a.error("end tag name: "+_+" is not complete:"+b.tagName),v=y+1+_.length):_.match(/\s</)&&(_=_.replace(/[\s<].*/,""),a.error("end tag name: "+_+" maybe not complete"),v=y+1+_.length);var T=b.localNSMap,S=b.tagName==_;if(S||b.tagName&&b.tagName.toLowerCase()==_.toLowerCase()){if(r.endElement(b.uri,b.localName,_),T)for(var w in T)r.endPrefixMapping(w);S||a.fatalError("end tag name: "+_+" is not match the current start tagName:"+b.tagName)}else h.push(b);v++;break;case"?":d&&o(y),v=function(e,t,i){var n=e.indexOf("?>",t);if(n){t=e.substring(t,n).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);return t?(t[0].length,i.processingInstruction(t[1],t[2]),n+2):-1}return-1}(i,y,r);break;case"!":d&&o(y),v=function(e,t,i,n){{if("-"===e.charAt(t+2)){if("-"!==e.charAt(t+3))return-1;var r=e.indexOf("--\x3e",t+4);return t<r?(i.comment(e,t+4,r-t-4),r+3):(n.error("Unclosed comment"),-1)}if("CDATA["==e.substr(t+3,6)){r=e.indexOf("]]>",t+9);return i.startCDATA(),i.characters(e,t+9,r-t-9),i.endCDATA(),r+3}var a=function(e,t){var i,n=[],r=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;r.lastIndex=t,r.exec(e);for(;i=r.exec(e);)if(n.push(i),i[1])return n}(e,t),n=a.length;if(1<n&&/!doctype/i.test(a[0][0])){r=a[1][0],e=!1,t=!1;3<n&&(/^public$/i.test(a[2][0])?(e=a[3][0],t=4<n&&a[4][0]):/^system$/i.test(a[2][0])&&(t=a[3][0]));n=a[n-1];return i.startDTD(r,e,t),i.endDTD(),n.index+n[0].length}}return-1}(i,y,r,a);break;default:d&&o(y);var E=new Ka,k=h[h.length-1].currentNSMap,v=function(e,t,n,i,r,a){function s(e,t,i){n.attributeNames.hasOwnProperty(e)&&a.fatalError("Attribute "+e+" redefined"),n.addValue(e,t,i)}var o,u=++t,l=Ma;for(;;){var c=e.charAt(u);switch(c){case"=":if(l===Na)o=e.slice(t,u),l=Ba;else{if(l!==Ua)throw new Error("attribute equal must after attrName");l=Ba}break;case"'":case'"':if(l===Ba||l===Na){if(l===Na&&(a.warning('attribute value must after "="'),o=e.slice(t,u)),t=u+1,!(0<(u=e.indexOf(c,t))))throw new Error("attribute value no end '"+c+"' match");d=e.slice(t,u).replace(/&#?\w+;/g,r),s(o,d,t-1),l=ja}else{if(l!=Fa)throw new Error('attribute value must after "="');d=e.slice(t,u).replace(/&#?\w+;/g,r),s(o,d,t),a.warning('attribute "'+o+'" missed start quot('+c+")!!"),t=u+1,l=ja}break;case"/":switch(l){case Ma:n.setTagName(e.slice(t,u));case ja:case Ha:case qa:l=qa,n.closed=!0;case Fa:case Na:case Ua:break;default:throw new Error("attribute invalid close char('/')")}break;case"":return a.error("unexpected end of input"),l==Ma&&n.setTagName(e.slice(t,u)),u;case">":switch(l){case Ma:n.setTagName(e.slice(t,u));case ja:case Ha:case qa:break;case Fa:case Na:"/"===(d=e.slice(t,u)).slice(-1)&&(n.closed=!0,d=d.slice(0,-1));case Ua:l===Ua&&(d=o),l==Fa?(a.warning('attribute "'+d+'" missed quot(")!'),s(o,d.replace(/&#?\w+;/g,r),t)):(Oa.isHTML(i[""])&&d.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+d+'" missed value!! "'+d+'" instead!!'),s(d,d,t));break;case Ba:throw new Error("attribute value missed!!")}return u;case"Â":c=" ";default:if(c<=" ")switch(l){case Ma:n.setTagName(e.slice(t,u)),l=Ha;break;case Na:o=e.slice(t,u),l=Ua;break;case Fa:var d=e.slice(t,u).replace(/&#?\w+;/g,r);a.warning('attribute "'+d+'" missed quot(")!!'),s(o,d,t);case ja:l=Ha}else switch(l){case Ua:n.tagName,Oa.isHTML(i[""])&&o.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+o+'" missed value!! "'+o+'" instead2!!'),s(o,o,t),t=u,l=Na;break;case ja:a.warning('attribute space is required"'+o+'"!!');case Ha:l=Na,t=u;break;case Ba:l=Fa,t=u;break;case qa:throw new Error("elements closed character '/' and '>' must be connected to")}}u++}}(i,y,E,k,s,a),C=E.length;if(!E.closed&&function(e,t,i,n){var r=n[i];null==r&&((r=e.lastIndexOf("</"+i+">"))<t&&(r=e.lastIndexOf("</"+i)),n[i]=r);return r<t}(i,v,E.tagName,p)&&(E.closed=!0,n.nbsp||a.warning("unclosed xml attribute")),d&&C){for(var I=Ga(d,{}),x=0;x<C;x++){var A=E[x];o(A.offset),A.locator=Ga(d,{})}r.locator=I,za(E,r,k)&&h.push(E),r.locator=d}else za(E,r,k)&&h.push(E);Oa.isHTML(E.uri)&&!E.closed?v=function(e,t,i,n,r){if(/^(?:script|textarea)$/i.test(i)){var a=e.indexOf("</"+i+">",t),e=e.substring(t+1,a);if(/[&<]/.test(e))return/^script$/i.test(i)||(e=e.replace(/&#?\w+;/g,n)),r.characters(e,0,e.length),a}return t+1}(i,v,E.tagName,s,r):v++}}catch(e){if(e instanceof Va)throw e;a.error("element parse error: "+e),v=-1}f<v?f=v:t(Math.max(y,f)+1)}}(e,t,i,n,this.errorHandler),n.endDocument()}},Ka.prototype={setTagName:function(e){if(!Ra.test(e))throw new Error("invalid tagName:"+e);this.tagName=e},addValue:function(e,t,i){if(!Ra.test(e))throw new Error("invalid attribute:"+e);this.attributeNames[e]=this.length,this[this.length++]={qName:e,value:t,offset:i}},length:0,getLocalName:function(e){return this[e].localName},getLocator:function(e){return this[e].locator},getQName:function(e){return this[e].qName},getURI:function(e){return this[e].uri},getValue:function(e){return this[e].value}};var x={XMLReader:Wa,ParseError:Va},Ya=U.DOMImplementation,Qa=Dr.NAMESPACE,$a=x.ParseError,Ja=x.XMLReader;function Za(e){this.options=e||{locator:{}}}function es(){this.cdata=!1}function ts(e,t){t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber}function is(e){if(e)return"\n@"+(e.systemId||"")+"#[line:"+e.lineNumber+",col:"+e.columnNumber+"]"}
vendor: 2,968 bytes, line 4716
4716function ns(e,t,i){return"string"==typeof e?e.substr(t,i):e.length>=t+i||t?new java.lang.String(e,t,i)+"":e}function rs(e,t){(e.currentElement||e.doc).appendChild(t)}Za.prototype.parseFromString=function(e,t){var i=this.options,n=new Ja,r=i.domBuilder||new es,a=i.errorHandler,s=i.locator,o=i.xmlns||{},u=/\/x?html?$/.test(t),t=u?Da.HTML_ENTITIES:Da.XML_ENTITIES;return s&&r.setDocumentLocator(s),n.errorHandler=function(n,e,r){if(!n){if(e instanceof es)return e;n=e}var a={},s=n instanceof Function;function t(t){var i=n[t];!i&&s&&(i=2==n.length?function(e){n(t,e)}:n),a[t]=i?function(e){i("[xmldom "+t+"]\t"+e+is(r))}:function(){}}return r=r||{},t("warning"),t("error"),t("fatalError"),a}(a,r,s),n.domBuilder=i.domBuilder||r,u&&(o[""]=Qa.HTML),o.xml=o.xml||Qa.XML,e&&"string"==typeof e?n.parse(e,o,t):n.errorHandler.error("invalid doc source"),r.doc},es.prototype={startDocument:function(){this.doc=(new Ya).createDocument(null,null,null),this.locator&&(this.doc.documentURI=this.locator.systemId)},startElement:function(e,t,i,n){var r=this.doc,a=r.createElementNS(e,i||t),s=n.length;rs(this,a),this.currentElement=a,this.locator&&ts(this.locator,a);for(var o=0;o<s;o++){var e=n.getURI(o),u=n.getValue(o),i=n.getQName(o),l=r.createAttributeNS(e,i);this.locator&&ts(n.getLocator(o),l),l.value=l.nodeValue=u,a.setAttributeNode(l)}},endElement:function(e,t,i){var n=this.currentElement;n.tagName,this.currentElement=n.parentNode},startPrefixMapping:function(e,t){},endPrefixMapping:function(e){},processingInstruction:function(e,t){t=this.doc.createProcessingInstruction(e,t);this.locator&&ts(this.locator,t),rs(this,t)},ignorableWhitespace:function(e,t,i){},characters:function(e,t,i){var n;(e=ns.apply(this,arguments))&&(n=this.cdata?this.doc.createCDATASection(e):this.doc.createTextNode(e),this.currentElement?this.currentElement.appendChild(n):/^\s*$/.test(e)&&this.doc.appendChild(n),this.locator&&ts(this.locator,n))},skippedEntity:function(e){},endDocument:function(){this.doc.normalize()},setDocumentLocator:function(e){(this.locator=e)&&(e.lineNumber=0)},comment:function(e,t,i){e=ns.apply(this,arguments);e=this.doc.createComment(e);this.locator&&ts(this.locator,e),rs(this,e)},startCDATA:function(){this.cdata=!0},endCDATA:function(){this.cdata=!1},startDTD:function(e,t,i){var n=this.doc.implementation;n&&n.createDocumentType&&(i=n.createDocumentType(e,t,i),this.locator&&ts(this.locator,i),rs(this,i),this.doc.doctype=i)},warning:function(e){},error:function(e){},fatalError:function(e){throw new $a(e,this.locator)}},"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(e){es.prototype[e]=function(){return null}});function as(e){return!!e&&"object"==typeof e}function ss(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return t.reduce(function(t,i){return"object"!=typeof i||Object.keys(i).forEac
4716h(function(e){Array.isArray(t[e])&&Array.isArray(i[e])?t[e]=t[e].concat(i[e]):as(t[e])&&as(i[e])?t[e]=ss(t[e],i[e]):t[e]=i[e]}),t},{})}function os(t){return Object.keys(t).map(function(e){return t[e]})}function us(e){return e.reduce(function(e,t){return e.concat(t)},[])}function ls(e){if(!e.length)return[];for(var t=[],i=0;i<e.length;i++)t.push(e[i]);return t}function cs(e,t){for(var i=0;i<e.length;i++)if(t(e[i]))return i;return-1}function ds(e){var t=e.baseUrl,i=void 0===(n=e.source)?"":n,n=void 0===(n=e.range)?"":n,e=void 0===(e=e.indexRange)?"":e,i={uri:i,resolvedUri:ir((void 0===t?"":t)||"",i)};return(n||e)&&(n=(n||e).split("-"),e=window.BigInt?window.BigInt(n[0]):parseInt(n[0],10),n=window.BigInt?window.BigInt(n[1]):parseInt(n[1],10),e<Number.MAX_SAFE_INTEGER&&"bigint"==typeof e&&(e=Number(e)),"bigint"==typeof(n="bigint"==typeof(n=n<Number.MAX_SAFE_INTEGER&&"bigint"==typeof n?Number(n):n)||"bigint"==typeof e?window.BigInt(n)-window.BigInt(e)+window.BigInt(1):n-e+1)&&n<Number.MAX_SAFE_INTEGER&&(n=Number(n)),i.byterange={length:n,offset:e}),i}function hs(e){return e&&"number"!=typeof e&&(e=parseInt(e,10)),isNaN(e)?null:e}function ps(e){var a,t=e.type,i=e.duration,n=e.timescale,r=void 0===n?1:n,s=e.periodDuration,o=e.sourceDuration,e=function(e,t){for(var i=[],n=e;n<t;n++)i.push(n);return i}((n=ho[t](e)).start,n.end).map((a=e,function(e){var t=a.duration,i=a.timescale,n=a.periodStart,r=a.startNumber;return{number:(void 0===r?1:r)+e,duration:t/(void 0===i?1:i),timeline:n,time:e*t}}));return"static"===t&&(e[t=e.length-1].duration=("number"==typeof s?s:o)-i/r*t),e}function fs(e){var t=e.baseUrl,i=void 0===(u=e.initialization)?{}:u,n=e.sourceDuration,r=void 0===(o=e.indexRange)?"":o,a=e.periodStart,s=e.presentationTime,o=void 0===(u=e.number)?0:u,u=e.duration;if(!t)throw new Error(uo);return i=ds({baseUrl:t,source:i.sourceURL,range:i.range}),(r=ds({baseUrl:t,source:t,indexRange:r})).map=i,u?(e=ps(e)).length&&(r.duration=e[0].duration,r.timeline=e[0].timeline):n&&(r.duration=n,r.timeline=a),r.presentationTime=s||a,r.number=o,[r]}function ms(e,t,i){for(var n=e.sidx.map||null,r=e.sidx.duration,a=e.timeline||0,s=(s=e.sidx.byterange).offset+s.length,o=t.timescale,u=t.references.filter(function(e){return 1!==e.referenceType}),l=[],c=e.endList?"static":"dynamic",d=e.sidx.timeline,h=d,p=e.mediaSequence||0,f="bigint"==typeof t.firstOffset?window.BigInt(s)+t.firstOffset:s+t.firstOffset,m=0;m<u.length;m++){var g=t.references[m],y=g.referencedSize,v=g.subsegmentDuration,g=void 0,g="bigint"==typeof f?f+window.BigInt(y)-window.BigInt(1):f+y-1,g=fs({baseUrl:i,timescale:o,timeline:a,periodStart:d,presentationTime:h,number:p,duration:v,sourceDuration:r,indexRange:f+"-"+g,type:c})[0];n&&(g.map=n),l.push(g),f+="bigint"==typeof f?window.BigInt(y):y,h+=v/o,p++}return e.segments=l,e}function gs(e){return i=function(e){return e.timeline},os(e.reduce(function(t,e){return e.forEach(function(e){t[i(e)]=e}),t},{})).sort(function(e,t){return e.timeline>t.timeline?1:-1});var i}function ys(e){var r,a,s=[];return r=e,a=function(e,t,i,n){s=s.concat(e.playlists||[])},po.forEach(function(e){for(var t in r.mediaGroups[e])for(var i in r.mediaGroups[e][t]){var n=r.mediaGroups[e][t][i];a(n,e,t,i)}}),s}function vs(e){var i=e.playlist,e=e.mediaSequence;i.mediaSequence=e,i.segments.forEach(function(e,t){e.number=i.mediaSequence+t})}function _s(e){var r,a,t=e.oldManifest,i=e.newManifest,n=t.playlists.concat(ys(t)),e=i.playlists.concat(ys(i));return i.timelineStarts=gs([t.timelineStarts,i.timelineStarts]),n={oldPlaylists:n,newPlaylists:e,timelineStarts:i.timelineStarts},r=n.oldPlaylists,e=n.newPlaylists,a=n.timelineStarts,e.forEach(function(t){t.discontinuitySequence=cs(a,function(e){return e.timeline===t.timeline});var e=function(e,t){for(var i=0;i<e.length;i++)if(e[i].attributes.NAME===t)return e[i];return null}(r,t.attributes.NAME);if(e&&!t.sidx){var i=t.segments[0],n=cs(e.segments,function(e){return Math.abs(e.presentationTime-i.presentationTime)<1/60});if(-1===n)return vs({playlist:t,mediaSequence:e.mediaSequence+e.segments.length}),t.segments[0].discontinuity=!0,t.discontinuityStarts.unshift(0),void((!e.segments.length&&t.timeline>e.timeline||e.segments.length&&t.timeline>e.segments[e.segments.length-1].timeline)&&t.discontinuitySequence--);e.segments[n].discontinuity&&!i.discontinuity&&(i.discontinuity=!0,t.discontinuityStarts.unshift(0),t.discontinuitySequence--),vs({playlist:t,mediaSequence:e.segments[n].number})}}),i}function bs(e){return e&&e.uri+"-"+(t=e.byterange,e="bigint"==typeof t.offset||"bigint"==typeof t.length?window.BigInt(t.offset)+window.BigInt(t.length)-window.BigInt(1):t.offset+t.length-1,t.offset+"-"+e);var t}function Ts(e){return os(e.reduce(function(e,t){var i,n=t.attributes.id+(t.attributes.lang||"");return e[n]?(t.segments&&(t.segments[0]&&(t.segments[0].discontinuity=!0),(i=e[n].segments).push.apply(i,t.segments)),t.attributes.contentProtection&&(e[n].attributes.contentProtection=t.attributes.contentProtection)):(e[n]=t,e[n].attributes.timelineStarts=[]),e[n].attributes.timelineStarts.push({start:t.attributes.periodStart,timeline:t.attributes.periodStart}),e},{})).map(function(e){var t,n;return e.discontinuityStarts=(t=e.segments||[],n="discontinuity",t.reduce(function(e,t,i){return t[n]&&e.push(i),e},[])),e})}function Ss(e,t){var i=bs(e.sidx);return(i=i&&t[i]&&t[i].sidx)&&ms(e,i,e.sidx.resolvedUri),e}function ws(e,h,p){var f;return void 0===h&&(h={}),void 0===p&&(p=!1),e=e.reduce(function(e,t){var i=t.attributes.role&&t.attributes.role.value||"",n=t.attributes.lang||"",r=t.attributes.label||"main";e[r=n&&!t.attributes.label?t.attributes.lang+(i?" ("+i+")":""):r]||(e[r]={language:n,autoselect:!0,default:"main"===i,playlists:[],uri:""});var a,s,o,u,l,c,d,u=Ss((s=p,o=(a=t).attributes,u=a.segments,l=a.sidx,c=a.mediaSequence,d=a.discontinuitySequence,n=a.discontinuityStarts,u={attributes:((a={NAME:o.id,BANDWIDTH:o.bandwidth,CODECS:o.codecs})["PROGRAM-ID"]=1,a),uri:"",endList:"static"===o.type,timeline:o.periodStart,resolvedUri:"",targetDuration:o.duration,discontinuitySequence:d,discontinuityStarts:n,timelineStarts:o.timelineStarts,mediaSequence:c,segments:u},o.contentProtection&&(u.contentProtection=o.contentProtection),l&&(u.sidx=l),s&&(u.attributes.AUDIO="audio",u.attributes.SUBTITLES="subs"),u),h);return e[r].playlists.push(u),"undefined"==typeof f&&"main"===i&&((f=t).default=!0),e},{}),f||(e[Object.keys(e)[0]].default=!0),e}function Es(e){var t=e.attributes,i=e.segments,n=e.sidx,r=e.discontinuityStarts,i={attributes:((e={NAME:t.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:t.width,height:t.height},CODECS:t.codecs,BANDWIDTH:t.bandwidth})["PROGRAM-ID"]=1,e),uri:"",endList:"static"===t.type,timeline:t.periodStart,resolvedUri:"",targetDuration:t.duration,discontinuityStarts:r,timelineStarts:t.timelineStarts,segments:i};return t.contentProtection&&(i.contentProtection=t.contentProtection),n&&(i.sidx=n),i}function ks(e){return"video/mp4"===(e=e.attributes).mimeType||"video/webm"===e.mimeType||"video"===e.contentType}function Cs(e){return"audio/mp4"===(e=e.attributes).mimeType||"audio/webm"===e.mimeType||"audio"===e.contentType}function Is(e){return"text/vtt"===(e=e.attributes).mimeType||"text"===e.contentType}function xs(i){return i?Object.keys(i).reduce(function(e,t){t=i[t];return e.concat(t.playlists)},[]):[]}function As(e){var t=e.dashPlaylists,i=e.locations,n=void 0===(c=e.sidxMapping)?{}:c,r=e.previousManifest;if(!t.length)return{};var a=(d=t[0].attributes).sourceDuration,s=d.type,o=d.suggestedPresentationDelay,u=d.minimumUpdatePeriod,l=Ts(t.filter(ks)).map(Es),c=Ts(t.filter(Cs)),e=Ts(t.filter(Is)),d=t.map(function(e){return e.attributes.captionServices}
4716).filter(Boolean),a={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:((t={AUDIO:{},VIDEO:{}})["CLOSED-CAPTIONS"]={},t.SUBTITLES={},t),uri:"",duration:a,playlists:function(e,t){if(void 0===t&&(t={}),!Object.keys(t).length)return e;for(var i in e)e[i]=Ss(e[i],t);return e}(l,n)};0<=u&&(a.minimumUpdatePeriod=1e3*u),i&&(a.locations=i),"dynamic"===s&&(a.suggestedPresentationDelay=o);var h,p,o=0===a.playlists.length,o=c.length?ws(c,n,o):null,n=e.length?(void 0===(h=n)&&(h={}),e.reduce(function(e,t){var i=t.attributes.lang||"text";return e[i]||(e[i]={language:i,default:!1,autoselect:!1,playlists:[],uri:""}),e[i].playlists.push(Ss(function(e){var t=e.attributes,i=e.segments,n=e.mediaSequence,r=e.discontinuityStarts,a=e.discontinuitySequence;"undefined"==typeof i&&(i=[{uri:t.baseUrl,timeline:t.periodStart,resolvedUri:t.baseUrl||"",duration:t.sourceDuration,number:0}],t.duration=t.sourceDuration);(e={NAME:t.id,BANDWIDTH:t.bandwidth})["PROGRAM-ID"]=1;return t.codecs&&(e.CODECS=t.codecs),{attributes:e,uri:"",endList:"static"===t.type,timeline:t.periodStart,resolvedUri:t.baseUrl||"",targetDuration:t.duration,timelineStarts:t.timelineStarts,discontinuityStarts:r,discontinuitySequence:a,mediaSequence:n,segments:i}}(t),h)),e},{})):null,l=(e=l.concat(xs(o),xs(n))).map(function(e){return e.timelineStarts});return a.timelineStarts=gs(l),e=e,p=a.timelineStarts,e.forEach(function(t){t.mediaSequence=0,t.discontinuitySequence=cs(p,function(e){return e.timeline===t.timeline}),t.segments&&t.segments.forEach(function(e,t){e.number=t})}),o&&(a.mediaGroups.AUDIO.audio=o),n&&(a.mediaGroups.SUBTITLES.subs=n),d.length&&(a.mediaGroups["CLOSED-CAPTIONS"].cc=d.reduce(function(n,e){return e&&e.forEach(function(e){var t=e.channel,i=e.language;n[i]={autoselect:!1,default:!1,instreamId:t,language:i},e.hasOwnProperty("aspectRatio")&&(n[i].aspectRatio=e.aspectRatio),e.hasOwnProperty("easyReader")&&(n[i].easyReader=e.easyReader),e.hasOwnProperty("3D")&&(n[i]["3D"]=e["3D"])}),n},{})),r?_s({oldManifest:r,newManifest:a}):a}function Ps(e,t){for(var i,n,r,a,s,o,u=e.type,l=e.minimumUpdatePeriod,c=void 0===l?0:l,d=void 0===(l=e.media)?"":l,h=e.sourceDuration,p=void 0===(l=e.timescale)?1:l,f=void 0===(l=e.startNumber)?1:l,m=e.periodStart,g=[],y=-1,v=0;v<t.length;v++){var _=t[v],b=_.d,T=_.r||0,S=_.t||0;y<0&&(y=S),S&&y<S&&(y=S);var w,E=void 0;E=T<0?(w=v+1)===t.length?"dynamic"===u&&0<c&&0<d.indexOf("$Number$")?(i=y,n=b,_=o=s=a=r=void 0,r=(S=e).NOW,a=S.clientOffset,s=S.availabilityStartTime,o=S.timescale,_=S.periodStart,S=S.minimumUpdatePeriod,Math.ceil((((r+a)/1e3+(void 0===S?0:S)-(s+(void 0===_?0:_)))*(void 0===o?1:o)-i)/n)):(h*p-y)/b:(t[w].t-y)/b:T+1;for(var k=f+g.length+E,C=f+g.length;C<k;)g.push({number:C,duration:b/p,time:y,timeline:m}),y+=b,C++}return g}function Ls(e,t){return e.replace(fo,(r=t,function(e,t,i,n){if("$$"===e)return"$";if("undefined"==typeof r[t])return e;e=""+r[t];return"RepresentationID"===t||(n=i?parseInt(n,10):1)<=e.length?e:new Array(n-e.length+1).join("0")+e}));var r}function Ds(r,e){var a={RepresentationID:r.id,Bandwidth:r.bandwidth||0},t=void 0===(t=r.initialization)?{sourceURL:"",range:""}:t,s=ds({baseUrl:r.baseUrl,source:Ls(t.sourceURL,a),range:t.range});return(t=e,(e=r).duration||t?e.duration?ps(e):Ps(e,t):[{number:e.startNumber||1,duration:e.sourceDuration,time:0,timeline:e.periodStart}]).map(function(e){a.Number=e.number,a.Time=e.time;var t=Ls(r.media||"",a),i=r.timescale||1,n=r.presentationTimeOffset||0,i=r.periodStart+(e.time-n)/i;return{uri:t,timeline:e.timeline,duration:e.duration,resolvedUri:ir(r.baseUrl||"",t),map:s,number:e.number,presentationTime:i}})}function Os(r,e){var t=r.duration,i=void 0===(i=r.segmentUrls)?[]:i,a=r.periodStart;if(!t&&!e||t&&e)throw new Error(lo);var n,s=i.map(function(e){return i=e,e=(t=r).baseUrl,t=t.initialization,t=ds({baseUrl:e,source:(t=void 0===t?{}:t).sourceURL,range:t.range}),(i=ds({baseUrl:e,source:i.media,range:i.mediaRange})).map=t,i;var t,i});return t&&(n=ps(r)),(n=e?Ps(r,e):n).map(function(e,t){if(s[t]){var i=s[t],n=r.timescale||1,t=r.presentationTimeOffset||0;return i.timeline=e.timeline,i.duration=e.duration,i.number=e.number,i.presentationTime=a+(e.time-t)/n,i}}).filter(function(e){return e})}function Rs(e){var t,i=e.attributes,n=e.segmentInfo;n.template?(a=Ds,t=ss(i,n.template)):n.base?(a=fs,t=ss(i,n.base)):n.list&&(a=Os,t=ss(i,n.list));var r={attributes:i};if(!a)return r;var a,e=a(t,n.segmentTimeline);return t.duration?(i=t.duration,a=t.timescale,t.duration=i/(void 0===a?1:a)):e.length?t.duration=e.reduce(function(e,t){return Math.max(e,Math.ceil(t.duration))},0):t.duration=0,r.attributes=t,r.segments=e,n.base&&t.indexRange&&(r.sidx=e[0],r.segments=[]),r}function Ms(e,t){return ls(e.childNodes).filter(function(e){return e.tagName===t})}function Ns(e){return e.textContent.trim()}function Us(e){if(!(r=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(e)))return 0;var t=(a=r.slice(1))[0],i=a[1],n=a[2],e=a[3],r=a[4],a=a[5];
4716return 31536e3*parseFloat(t||0)+2592e3*parseFloat(i||0)+86400*parseFloat(n||0)+3600*parseFloat(e||0)+60*parseFloat(r||0)+parseFloat(a||0)}function Bs(e){return e&&e.attributes?ls(e.attributes).reduce(function(e,t){var i=mo[t.name]||mo.DEFAULT;return e[t.name]=i(t.value),e},{}):{}}function Fs(e,i){return i.length?us(e.map(function(t){return i.map(function(e){return ir(t,Ns(e))})})):e}function js(e){var t=Ms(e,"SegmentTemplate")[0],i=Ms(e,"SegmentList")[0],n=i&&Ms(i,"SegmentURL").map(function(e){return ss({tag:"SegmentURL"},Bs(e))}),r=Ms(e,"SegmentBase")[0],e=(a=i||t)&&Ms(a,"SegmentTimeline")[0],a=(a=i||r||t)&&Ms(a,"Initialization")[0];(t=t&&Bs(t))&&a?t.initialization=a&&Bs(a):t&&t.initialization&&(t.initialization={sourceURL:t.initialization});var s={template:t,segmentTimeline:e&&Ms(e,"S").map(Bs),list:i&&ss(Bs(i),{segmentUrls:n,initialization:Bs(a)}),base:r&&ss(Bs(r),{initialization:Bs(a)})};return Object.keys(s).forEach(function(e){s[e]||delete s[e]}),s}function Hs(u,l,c){return function(e){var t=Bs(e),i=Fs(l,Ms(e,"BaseURL")),n=Ms(e,"Role")[0],n={role:Bs(n)},t=ss(u,t,n),n=Ms(e,"Accessibility")[0],n="urn:scte:dash:cc:cea-608:2015"===(n=Bs(n)).schemeIdUri?("string"!=typeof n.value?[]:n.value.split(";")).map(function(e){var t,i,n;return/^CC\d=/.test(n=e)?(i=(t=e.split("="))[0],n=t[1]):/^CC\d$/.test(e)&&(i=e),{channel:i,language:n}}):"urn:scte:dash:cc:cea-708:2015"===n.schemeIdUri?("string"!=typeof n.value?[]:n.value.split(";")).map(function(e){var t,i,n={channel:void 0,language:void 0,aspectRatio:1,easyReader:0,"3D":0};return/=/.test(e)?(t=(i=e.split("="))[0],i=void 0===(i=i[1])?"":i,n.channel=t,n.language=e,i.split(",").forEach(function(e){var t=e.split(":"),e=t[0],t=t[1];"lang"===e?n.language=t:"er"===e?n.easyReader=Number(t):"war"===e?n.aspectRatio=Number(t):"3D"===e&&(n["3D"]=Number(t))})):n.language=e,n.channel&&(n.channel="SERVICE"+n.channel),n}):void 0;n&&(t=ss(t,{captionServices:n}));n=Ms(e,"Label")[0];n&&n.childNodes.length&&(r=n.childNodes[0].nodeValue.trim(),t=ss(t,{label:r}));var r=Ms(e,"ContentProtection").reduce(function(e,t){var i=Bs(t),n=go[i.schemeIdUri];return n&&(e[n]={attributes:i},(t=Ms(t,"cenc:pssh")[0])&&(t=(t=Ns(t))&&or(t),e[n].pssh=t)),e},{});Object.keys(r).length&&(t=ss(t,{contentProtection:r}));var a,s,o,r=js(e),e=Ms(e,"Representation"),r=ss(c,r);return us(e.map((a=t,s=i,o=r,function(e){var t=Ms(e,"BaseURL"),t=Fs(s,t),i=ss(a,Bs(e)),n=js(e);return t.map(function(e){return{segmentInfo:ss(o,n),attributes:ss(i,{baseUrl:e})}})})))}}function qs(e,t){var i=t=void 0===t?{}:t,n=void 0===(a=i.manifestUri)?"":a,t=void 0===(r=i.NOW)?Date.now():r,r=void 0===(a=i.clientOffset)?0:a;if(!(i=Ms(e,"Period")).length)throw new Error(ao);var a=Ms(e,"Location"),s=Bs(e),e=Fs([n],Ms(e,"BaseURL"));s.type=s.type||"static",s.sourceDuration=s.mediaPresentationDuration||0,s.NOW=t,s.clientOffset=r,a.length&&(s.locations=a.map(Ns));var o,u,l=[];return i.forEach(function(e,t){var i,n=Bs(e),r=l[t-1];n.start=(i={attributes:n,priorPeriodAttributes:r?r.attributes:null,mpdType:s.type},t=i.attributes,r=i.priorPeriodAttributes,i=i.mpdType,"number"==typeof t.start?t.start:r&&"number"==typeof r.start&&"number"==typeof r.duration?r.start+r.duration:r||"static"!==i?null:0),l.push({node:e,attributes:n})}),{locations:s.locations,representationInfo:us(l.map((o=s,u=e,function(e,t){var i=Fs(u,Ms(e.node,"BaseURL")),n=ss(o,{periodStart:e.attributes.start});"number"==typeof e.attributes.duration&&(n.periodDuration=e.attributes.duration);var r=Ms(e.node,"AdaptationSet"),e=js(e.node);return us(r.map(Hs(n,i,e)))})))}}function Vs(e){if(""===e)throw new Error(so);var t,i,n=new ro;try{i=(t=n.parseFromString(e,"application/xml"))&&"MPD"===t.documentElement.tagName?t.documentElement:null}catch(e){}if(!i||i&&0<i.getElementsByTagName("parsererror").length)throw new Error(oo);return i}function Ws(e,t){void 0===t&&(t={});var i=qs(Vs(e),t),e=i.representationInfo.map(Rs);return As({dashPlaylists:e,locations:i.locations,sidxMapping:t.sidxMapping,previousManifest:t.previousManifest})}function Gs(e){return function(e){e=Ms(e,"UTCTiming")[0];if(!e)return null;var t=Bs(e);switch(t.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":t.method="HEAD";break;case"urn:mpeg:dash:utc:http-xsdate:2014":case"urn:mpeg:dash:utc:http-iso:2014":case"urn:mpeg:dash:utc:http-xsdate:2012":case"urn:mpeg:dash:utc:http-iso:2012":t.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":t.method="DIRECT",t.value=Date.parse(t.value);break;case"urn:mpeg:dash:utc:http-ntp:2014":case"urn:mpeg:dash:utc:ntp:2014":case"urn:mpeg:dash:utc:sntp:2014":default:throw new Error(co)}return t}(Vs(e))}function zs(e){return e instanceof Uint8Array?e:(Array.isArray(e)||(t=e,ArrayBuffer.isView(t))||e instanceof ArrayBuffer||(e="number"!=typeof e||"number"==typeof e&&e!=e?0:[e]),new Uint8Array(e&&e.buffer||e,e&&e.byteOffset||0,e&&e.byteLength||0));var t}function Xs(e,t){var i=void 0!==(t=(void 0===t?{}:t).le)&&t;e=bo(e="bigint"!=typeof e&&"number"!=typeof e||"number"==typeof e&&e!=e?0:e);
4716for(var n=(t=e,Math.ceil(t.toString(2).length/8)),r=new Uint8Array(new ArrayBuffer(n)),a=0;a<n;a++){var s=i?a:Math.abs(a+1-r.length);r[s]=Number(e/To[a]&bo(255)),e<0&&(r[s]=Math.abs(~r[s]),r[s]-=0===a?1:2)}return r}function Ks(e,t){if("string"!=typeof(e="string"!=typeof e&&e&&"function"==typeof e.toString?e.toString():e))return new Uint8Array;t||(e=unescape(encodeURIComponent(e)));for(var i=new Uint8Array(e.length),n=0;n<e.length;n++)i[n]=e.charCodeAt(n);return i}function Ys(i,e,t){var n=void 0===t?{}:t,r=void 0===(t=n.offset)?0:t,a=void 0===(n=n.mask)?[]:n;return i=zs(i),n=(e=zs(e)).every||Array.prototype.every,e.length&&i.length-r>=e.length&&n.call(e,function(e,t){return e===(a[t]?a[t]&i[r+t]:i[r+t])})}function Qs(e,t){return void 0===t&&(t=0),(e=zs(e)).length-t<10||!Ys(e,So,{offset:t})?t:Qs(e,t+=function(e,t){void 0===t&&(t=0);var i=(e=zs(e))[t+5],t=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&i)>>4?20+t:10+t}(e,t))}function $s(e){return"string"==typeof e?Ks(e):e}function Js(e,t,i){var n;void 0===i&&(i=!1),n=t,t=Array.isArray(n)?n.map($s):[$s(n)],e=zs(e);var r=[];if(!t.length)return r;for(var a=0;a<e.length;){var s=(e[a]<<24|e[a+1]<<16|e[a+2]<<8|e[a+3])>>>0,o=e.subarray(a+4,a+8);if(0==s)break;var u=a+s;if(u>e.length){if(i)break;u=e.length}s=e.subarray(a+8,u);Ys(o,t[0])&&(1===t.length?r.push(s):r.push.apply(r,Js(s,t.slice(1),i))),a=u}return r}function Zs(e,t,i,n){void 0===i&&(i=!0),void 0===n&&(n=!1);var r=function(e){for(var t=1,i=0;i<Eo.length&&!(e&Eo[i]);i++)t++;return t}(e[t]),a=e.subarray(t,t+r);return i&&((a=Array.prototype.slice.call(e,t,t+r))[0]^=Eo[r-1]),{length:r,value:function(n,e){var t=void 0===e?{}:e,e=t.signed,e=void 0!==e&&e,t=t.le,r=void 0!==t&&t;n=zs(n);t=r?"reduce":"reduceRight",t=(n[t]||Array.prototype[t]).call(n,function(e,t,i){i=r?i:Math.abs(i+1-n.length);return e+bo(t)*To[i]},bo(0));return!e||(e=To[n.length]/bo(2)-bo(1))<(t=bo(t))&&(t-=e,t-=e,t-=bo(2)),Number(t)}(a,{signed:n}),bytes:a}}function eo(e){return"string"==typeof e?e.match(/.{1,2}/g).map(eo):"number"==typeof e?Xs(e):e}function to(e,t,i){if(i>=t.length)return t.length;var n=Zs(t,i,!1);if(Ys(e.bytes,n.bytes))return i;var r=Zs(t,i+n.length);return to(e,t,i+r.length+r.value+n.length)}function io(e,t){var i;i=t,t=Array.isArray(i)?i.map(eo):[eo(i)],e=zs(e);var n=[];if(!t.length)return n;for(var r=0;r<e.length;){var a=Zs(e,r,!1),s=Zs(e,r+a.length),o=r+a.length+s.length;127===s.value&&(s.value=to(a,e,o),s.value!==e.length&&(s.value-=o));var u=o+s.value>e.length?e.length:o+s.value,u=e.subarray(o,u);Ys(t[0],a.bytes)&&(1===t.length?n.push(u):n=n.concat(io(u,t.slice(1)))),r+=a.length+s.length+u.length}return n}function no(e,t,i,n){void 0===n&&(n=1/0),e=zs(e),i=[].concat(i);for(var r,a=0,s=0;a<e.length&&(s<n||r);){var o=void 0;if(Ys(e.subarray(a),ko)?o=4:Ys(e.subarray(a),Co)&&(o=3),o){if(s++,r)return function(e){for(var t=[],i=1;i<e.length-2;)Ys(e.subarray(i,i+3),Io)&&(t.push(i+2),i++),i++;if(0===t.length)return e;for(var n=e.length-t.length,r=new Uint8Array(n),a=0,i=0;i<n;a++,i++)a===t[0]&&(a++,t.shift()),r[i]=e[a];return r}(e.subarray(r,a));var u=void 0;"h264"===t?u=31&e[a+o]:"h265"===t&&(u=e[a+o]>>1&63),-1!==i.indexOf(u)&&(r=a+o),a+=o+("h264"===t?1:2)}else a++}return e.subarray(0,0)}var ro={__DOMHandler:es,DOMParser:Za,DOMImplementation:U.DOMImplementation,XMLSerializer:U.XMLSerializer}.DOMParser,ao="INVALID_NUMBER_OF_PERIOD",so="DASH_EMPTY_MANIFEST",oo="DASH_INVALID_XML",uo="NO_BASE_URL",lo="SEGMENT_TIME_UNSPECIFIED",co="UNSUPPORTED_UTC_TIMING_SCHEME",ho={static:function(e){var t=e.duration,i=e.timescale,n=void 0===i?1:i,r=e.sourceDuration,i=e.periodDuration,e=hs(e.endNumber),n=t/n;return"number"==typeof e?{start:0,end:e}:"number"==typeof i?{start:0,end:i/n}:{start:0,end:r/n}},dynamic:function(e){var t=e.NOW,i=e.clientOffset,n=e.availabilityStartTime,r=e.timescale,a=void 0===r?1:r,s=e.duration,o=e.periodStart,u=void 0===o?0:o,r=e.minimumUpdatePeriod,o=void 0===r?0:r,r=e.timeShiftBufferDepth,r=void 0===r?1/0:r,e=hs(e.endNumber),i=(t+i)/1e3,u=n+u,o=Math.ceil((i+o-u)*a/s),r=Math.floor((i-u-r)*a/s),s=Math.floor((i-u)*a/s);return{start:Math.max(0,r),end:"number"==typeof e?e:Math.min(o,s)}}},po=["AUDIO","SUBTITLES"],fo=/\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g,mo={mediaPresentationDuration:Us,availabilityStartTime:function(e){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(e=e)&&(e+="Z"),Date.parse(e)/1e3},minimumUpdatePeriod:Us,suggestedPresentationDelay:Us,type:function(e){return e},timeShiftBufferDepth:Us,start:Us,width:function(e){return parseInt(e,10)},height:function(e){return parseInt(e,10)},bandwidth:function(e){return parseInt(e,10)},startNumber:function(e){return parseInt(e,10)},timescale:function(e){return parseInt(e,10)},presentationTimeOffset:function(e){return parseInt(e,10)},duration:function(e){var t=parseInt(e,10);return isNaN(t)?Us(e):t},d:function(e){return parseInt(e,10)},t:function(e){return parseInt(e,10)},r:function(e){return parseInt(e,10)},DEFAULT:function(e){return e}},go={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"},yo=Math.pow(2,32),vo=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return t.getBigUint64?(e=t.getBigUint64(0))<Number.MAX_SAFE_INTEGER?
4716Number(e):e:t.getUint32(0)*yo+t.getUint32(4)},_o=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),references:[],referenceId:t.getUint32(4),timescale:t.getUint32(8)},n=12;0===i.version?(i.earliestPresentationTime=t.getUint32(n),i.firstOffset=t.getUint32(n+4),n+=8):(i.earliestPresentationTime=vo(e.subarray(n)),i.firstOffset=vo(e.subarray(n+8)),n+=16);var r=t.getUint16(n+=2);for(n+=2;0<r;n+=12,r--)i.references.push({referenceType:(128&e[n])>>>7,referencedSize:2147483647&t.getUint32(n),subsegmentDuration:t.getUint32(n+4),startsWithSap:!!(128&e[n+8]),sapType:(112&e[n+8])>>>4,sapDeltaTime:268435455&t.getUint32(n+8)});return i},bo=window.BigInt||Number,To=[bo("0x1"),bo("0x100"),bo("0x10000"),bo("0x1000000"),bo("0x100000000"),bo("0x10000000000"),bo("0x1000000000000"),bo("0x100000000000000"),bo("0x10000000000000000")],So=zs([73,68,51]),wo={EBML:zs([26,69,223,163]),DocType:zs([66,130]),Segment:zs([24,83,128,103]),SegmentInfo:zs([21,73,169,102]),Tracks:zs([22,84,174,107]),Track:zs([174]),TrackNumber:zs([215]),DefaultDuration:zs([35,227,131]),TrackEntry:zs([174]),TrackType:zs([131]),FlagDefault:zs([136]),CodecID:zs([134]),CodecPrivate:zs([99,162]),VideoTrack:zs([224]),AudioTrack:zs([225]),Cluster:zs([31,67,182,117]),Timestamp:zs([231]),TimestampScale:zs([42,215,177]),BlockGroup:zs([160]),BlockDuration:zs([155]),Block:zs([161]),SimpleBlock:zs([163])},Eo=[128,64,32,16,8,4,2,1],ko=zs([0,0,0,1]),Co=zs([0,0,1]),Io=zs([0,0,3]),xo={webm:zs([119,101,98,109]),matroska:zs([109,97,116,114,111,115,107,97]),flac:zs([102,76,97,67]),ogg:zs([79,103,103,83]),ac3:zs([11,119]),riff:zs([82,73,70,70]),avi:zs([65,86,73]),wav:zs([87,65,86,69]),"3gp":zs([102,116,121,112,51,103]),mp4:zs([102,116,121,112]),fmp4:zs([115,116,121,112]),mov:zs([102,116,121,112,113,116]),moov:zs([109,111,111,118]),moof:zs([109,111,111,102])},Ao={aac:function(e){var t=Qs(e);return Ys(e,[255,16],{offset:t,mask:[255,22]})},mp3:function(e){var t=Qs(e);return Ys(e,[255,2],{offset:t,mask:[255,6]})},webm:function(e){e=io(e,[wo.EBML,wo.DocType])[0];return Ys(e,xo.webm)},mkv:function(e){e=io(e,[wo.EBML,wo.DocType])[0];return Ys(e,xo.matroska)},mp4:function(e){return!Ao["3gp"](e)&&!Ao.mov(e)&&(!(!Ys(e,xo.mp4,{offset:4})&&!Ys(e,xo.fmp4,{offset:4}))||(!(!Ys(e,xo.moof,{offset:4})&&!Ys(e,xo.moov,{offset:4}))||void 0))},mov:function(e){return Ys(e,xo.mov,{offset:4})},"3gp":function(e){return Ys(e,xo["3gp"],{offset:4})},ac3:function(e){var t=Qs(e);return Ys(e,xo.ac3,{offset:t})},ts:function(e){if(e.length<189&&1<=e.length)return 71===e[0];for(var t=0;t+188<e.length&&t<188;){if(71===e[t]&&71===e[t+188])return!0;t+=1}return!1},flac:function(e){var t=Qs(e);return Ys(e,xo.flac,{offset:t})},ogg:function(e){return Ys(e,xo.ogg)},avi:function(e){return Ys(e,xo.riff)&&Ys(e,xo.avi,{offset:8})},wav:function(e){return Ys(e,xo.riff)&&Ys(e,xo.wav,{offset:8})},h264:function(e){return no(e,"h264",7,3).length},h265:function(e){return no(e,"h265",[32,33],3).length}},Po=Object.keys(Ao).filter(function(e){return"ts"!==e&&"h264"!==e&&"h265"!==e}).concat(["ts","h264","h265"]);Po.forEach(function(e){var t=Ao[e];Ao[e]=function(e){return t(zs(e))}});function Lo(e){e=zs(e);for(var t=0;t<Po.length;t++){var i=Po[t];if(ll[i](e))return i}return""}function Do(e,t,i){return e&&i&&i.responseURL&&t!==i.responseURL?i.responseURL:t}function Oo(e){return tr.log.debug?tr.log.debug.bind(tr,"VHS:",e+" >"):function(){}}function Ro(e,t){var i,n=[];if(e&&e.length)for(i=0;i<e.length;i++)t(e.start(i),e.end(i))&&n.push([e.start(i),e.end(i)]);return tr.createTimeRanges(n)}function Mo(e,i){return Ro(e,function(e,t){return e-.1<=i&&i<=t+.1})}function No(e,t){return Ro(e,function(e){return t<=e-hl})}function Uo(e){var t=[];if(!e||!e.length)return"";for(var i=0;i<e.length;i++)t.push(e.start(i)+" => "+e.end(i));return t.join(", ")}function Bo(e){for(var t=[],i=0;i<e.length;i++)t.push({start:e.start(i),end:e.end(i)});return t}function Fo(e){if(e&&e.length&&e.end)return e.end(e.length-1)}function jo(e,t){var i=0;if(!e||!e.length)return i;for(var n=0;n<e.length;n++){var r=e.start(n),a=e.end(n);a<t||(i+=r<t&&t<=a?a-t:a-r)}return i}function Ho(t,e){if(!e.preload)return e.duration;var i=0;
4716return(e.parts||[]).forEach(function(e){i+=e.duration}),(e.preloadHints||[]).forEach(function(e){"PART"===e.type&&(i+=t.partTargetDuration)}),i}function qo(e){return(e.segments||[]).reduce(function(i,n,r){return n.parts?n.parts.forEach(function(e,t){i.push({duration:e.duration,segmentIndex:r,partIndex:t,part:e,segment:n})}):i.push({duration:n.duration,segmentIndex:r,partIndex:null,segment:n,part:null}),i},[])}function Vo(e){return(e=e.segments&&e.segments.length&&e.segments[e.segments.length-1])&&e.parts||[]}function Wo(e){var t=e.preloadSegment;if(t){e=t.parts,t=(t.preloadHints||[]).reduce(function(e,t){return e+("PART"===t.type?1:0)},0);return t+=e&&e.length?e.length:0}}function Go(e,t){return t.endList?0:e&&e.suggestedPresentationDelay?e.suggestedPresentationDelay:(e=0<Vo(t).length)&&t.serverControl&&t.serverControl.partHoldBack?t.serverControl.partHoldBack:e&&t.partTargetDuration?3*t.partTargetDuration:t.serverControl&&t.serverControl.holdBack?t.serverControl.holdBack:t.targetDuration?3*t.targetDuration:0}function zo(e,t,i){if((t="undefined"==typeof t?e.mediaSequence+e.segments.length:t)<e.mediaSequence)return 0;var n=function(e,t){var i=0,n=t-e.mediaSequence,r=e.segments[n];if(r){if("undefined"!=typeof r.start)return{result:r.start,precise:!0};if("undefined"!=typeof r.end)return{result:r.end-r.duration,precise:!0}}for(;n--;){if("undefined"!=typeof(r=e.segments[n]).end)return{result:i+r.end,precise:!0};if(i+=Ho(e,r),"undefined"!=typeof r.start)return{result:i+r.start,precise:!0}}return{result:i,precise:!1}}(e,t);return n.precise?n.result:(t=function(e,t){for(var i,n=0,r=t-e.mediaSequence;r<e.segments.length;r++){if("undefined"!=typeof(i=e.segments[r]).start)return{result:i.start-n,precise:!0};if(n+=Ho(e,i),"undefined"!=typeof i.end)return{result:i.end-n,precise:!0}}return{result:-1,precise:!1}}(e,t)).precise?t.result:n.result+i}function Xo(e,t,i){if(!e)return 0;if("number"!=typeof i&&(i=0),"undefined"==typeof t){if(e.totalDuration)return e.totalDuration;if(!e.endList)return window.Infinity}return zo(e,t,i)}function Ko(e){var t=e.defaultDuration,i=e.durationList,n=e.startIndex,r=e.endIndex,a=0;if(r<n&&(n=(e=[r,n])[0],r=e[1]),n<0){for(var s=n;s<Math.min(0,r);s++)a+=t;n=0}for(var o=n;o<r;o++)a+=i[o].duration;return a}function Yo(e,t,i,n){return e&&e.segments?e.endList?Xo(e):null===t?null:(t=zo(e,e.mediaSequence+e.segments.length,t=t||0),i&&(t-=n="number"==typeof n?n:Go(null,e)),Math.max(0,t)):null}function Qo(e){return e.excludeUntil&&e.excludeUntil>Date.now()}function $o(e){return e.excludeUntil&&e.excludeUntil===1/0}function Jo(e){var t=Qo(e);return!e.disabled&&!t}function Zo(e,t){return t.attributes&&t.attributes[e]}function eu(e,t){if(1===e.playlists.length)return!0;var i=t.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===e.playlists.filter(function(e){return!!Jo(e)&&(e.attributes.BANDWIDTH||0)<i}).length}function tu(e,t){return!(!e&&!t||!e&&t||e&&!t)&&(e===t||(!(!e.id||!t.id||e.id!==t.id)||(!(!e.resolvedUri||!t.resolvedUri||e.resolvedUri!==t.resolvedUri)||!(!e.uri||!t.uri||e.uri!==t.uri))))}function iu(e,t){var i,n=e&&e.mediaGroups&&e.mediaGroups.AUDIO||{},r=!1;for(i in n){for(var a in n[i])if(r=t(n[i][a]))break;if(r)break}return!!r}function nu(i){if(!i||!i.playlists||!i.playlists.length)return iu(i,function(e){return e.playlists&&e.playlists.length||e.uri});for(var e=0;e<i.playlists.length;e++){var t=function(e){var t=i.playlists[e],e=t.attributes&&t.attributes.CODECS;return e&&e.split(",").every(fr)||iu(i,function(e){return tu(t,e)})?"continue":{v:!1}}(e);if("continue"!==t&&"object"==typeof t)return t.v}return!0}function ru(e,t){return e+"-"+t}function au(r,a){r.mediaGroups&&["AUDIO","SUBTITLES"].forEach(function(e){if(r.mediaGroups[e])for(var t in r.mediaGroups[e])for(var i in r.mediaGroups[e][t]){var n=r.mediaGroups[e][t][i];a(n,e,t,i)}})}function su(e){var t=e.playlist,i=e.uri,e=e.id;t.id=e,t.playlistErrors_=0,i&&(t.uri=i),t.attributes=t.attributes||{}}function ou(o,e){o.uri=e;for(var t=0;t<o.playlists.length;t++)o.playlists[t].uri||(o.playlists[t].uri="placeholder-uri-"+t);var i,u=nu(o);au(o,function(e,t,i,n){var r="placeholder-uri-"+t+"-"+i+"-"+n;if(!e.playlists||!e.playlists.length){if(u&&"AUDIO"===t&&!e.uri)for(var a=0;a<o.playlists.length;a++){var s=o.playlists[a];if(s.attributes&&s.attributes.AUDIO&&s.attributes.AUDIO===i)return}e.playlists=[g({},e)]}
4716e.playlists.forEach(function(e,t){var i=ru(t,r);e.uri?e.resolvedUri=e.resolvedUri||dl(o.uri,e.uri):(e.uri=0===t?r:i,e.resolvedUri=e.uri),e.id=e.id||i,e.attributes=e.attributes||{},o.playlists[e.id]=e,o.playlists[e.uri]=e})}),function(e){for(var t=e.playlists.length;t--;){var i=e.playlists[t];su({playlist:i,id:ru(t,i.uri)}),i.resolvedUri=dl(e.uri,i.uri),e.playlists[i.id]=i,(e.playlists[i.uri]=i).attributes.BANDWIDTH||ml.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute.")}}(o),au(i=o,function(e){e.uri&&(e.resolvedUri=dl(i.uri,e.uri))})}function uu(e,t,i){var n=e.slice(),r=t.slice();i=i||0;for(var a,s=[],o=0;o<r.length;o++){var u=n[o+i],l=r[o];u?(a=u.map||a,s.push(function(e,t){if(!e)return t;var i=gl(e,t);if(e.preloadHints&&!t.preloadHints&&delete i.preloadHints,e.parts&&!t.parts)delete i.parts;else if(e.parts&&t.parts)for(var n=0;n<t.parts.length;n++)e.parts&&e.parts[n]&&(i.parts[n]=gl(e.parts[n],t.parts[n]));return!e.skipped&&t.skipped&&(i.skipped=!1),e.preload&&!t.preload&&(i.preload=!1),i}
4716(u,l))):(a&&!l.map&&(l.map=a),s.push(l))}return s}function lu(e,t){!e.resolvedUri&&e.uri&&(e.resolvedUri=dl(t,e.uri)),e.key&&!e.key.resolvedUri&&(e.key.resolvedUri=dl(t,e.key.uri)),e.map&&!e.map.resolvedUri&&(e.map.resolvedUri=dl(t,e.map.uri)),e.map&&e.map.key&&!e.map.key.resolvedUri&&(e.map.key.resolvedUri=dl(t,e.map.key.uri)),e.parts&&e.parts.length&&e.parts.forEach(function(e){e.resolvedUri||(e.resolvedUri=dl(t,e.uri))}),e.preloadHints&&e.preloadHints.length&&e.preloadHints.forEach(function(e){e.resolvedUri||(e.resolvedUri=dl(t,e.uri))})}function cu(e){var t=e.segments||[],i=e.preloadSegment;if(i&&i.parts&&i.parts.length){if(i.preloadHints)for(var n=0;n<i.preloadHints.length;n++)if("MAP"===i.preloadHints[n].type)return t;i.duration=e.targetDuration,i.preload=!0,t.push(i)}return t}function du(e,t){return e===t||e.segments&&t.segments&&e.segments.length===t.segments.length&&e.endList===t.endList&&e.mediaSequence===t.mediaSequence&&e.preloadSegment===t.preloadSegment}function hu(e,a,t){void 0===t&&(t=du);var i=gl(e,{}),n=i.playlists[a.id];if(!n)return null;if(t(n,a))return null;a.segments=cu(a);var r=gl(n,a);if(r.preloadSegment&&!a.preloadSegment&&delete r.preloadSegment,n.segments){if(a.skip){a.segments=a.segments||[];for(var s=0;s<a.skip.skippedSegments;s++)a.segments.unshift({skipped:!0})}r.segments=uu(n.segments,a.segments,a.mediaSequence-n.mediaSequence)}r.segments.forEach(function(e){lu(e,r.resolvedUri)});for(var o=0;o<i.playlists.length;o++)i.playlists[o].id===a.id&&(i.playlists[o]=r);return i.playlists[a.id]=r,i.playlists[a.uri]=r,au(e,function(e,t,i,n){if(e.playlists)for(var r=0;r<e.playlists.length;r++)a.id===e.playlists[r].id&&(e.playlists[r]=a)}),i}function pu(e,t){var i=e.segments||[],n=i[i.length-1],n=(i=n&&n.parts&&n.parts[n.parts.length-1])&&i.duration||n&&n.duration;return t&&n?1e3*n:500*(e.partTargetDuration||e.targetDuration||10)}function fu(e,t,i,n){var r="arraybuffer"===e.responseType?e.response:e.responseText;!t&&r&&(e.responseTime=Date.now(),e.roundTripTime=e.responseTime-e.requestTime,e.bytesReceived=r.byteLength||r.length,e.bandwidth||(e.bandwidth=Math.floor(e.bytesReceived/e.roundTripTime*8*1e3))),i.headers&&(e.responseHeaders=i.headers),t&&"ETIMEDOUT"===t.code&&(e.timedout=!0),n(t=!t&&!e.aborted&&200!==i.statusCode&&206!==i.statusCode&&0!==i.statusCode?new Error("XHR Failed with a response of: "+(e&&(r||e.responseText))):t,e)}function mu(){function a(e,i){e=_l({timeout:45e3},e);var t=a.beforeRequest||tr.Vhs.xhr.beforeRequest;!t||"function"!=typeof t||(t=t(e))&&(e=t);var n=(!0===tr.Vhs.xhr.original?vl:tr.Vhs.xhr)(e,function(e,t){return fu(n,e,t,i)}),r=n.abort;return n.abort=function(){return n.aborted=!0,r.apply(n,arguments)},n.uri=e.uri,n.requestTime=Date.now(),n}return a.original=!0,a}function gu(e){var t,i={};return e.byterange&&(i.Range=(t=e.byterange,e=t.offset,t="bigint"==typeof t.offset||"bigint"==typeof t.length?window.BigInt(t.offset)+window.BigInt(t.length)-window.BigInt(1):t.offset+t.length-1,"bytes="+e+"-"+t)),i}function yu(e,t){return e=e.toString(16),"00".substring(0,2-e.length)+e+(t%2?" ":"")}function vu(e){return 32<=e&&e<126?String.fromCharCode(e):"."}function _u(i){var n={};
4716return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}function bu(e){var t=e.byterange||{length:1/0,offset:0};return[t.length,t.offset,e.resolvedUri].join(",")}function Tu(e){return e.resolvedUri}function Su(e){for(var t=Array.prototype.slice.call(e),i="",n=0;n<t.length/16;n++)i+=t.slice(16*n,16*n+16).map(yu).join("")+" "+t.slice(16*n,16*n+16).map(vu).join("")+"\n";return i}function wu(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i;if(!(i=e.callback))throw new Error("getProgramTime: callback must be provided");return t&&void 0!==n?(e=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i,n=0,r=0;r<t.segments.length&&!(e<=(n=(i=t.segments[r]).videoTimingInfo?i.videoTimingInfo.transmuxedPresentationEnd:n+i.duration));r++);var a=t.segments[t.segments.length-1];if(a.videoTimingInfo&&a.videoTimingInfo.transmuxedPresentationEnd<e)return null;if(n<e){if(e>n+.25*a.duration)return null;i=a}return{segment:i,estimatedStart:i.videoTimingInfo?i.videoTimingInfo.transmuxedPresentationStart:n-i.duration,type:i.videoTimingInfo?"accurate":"estimate"}}(n,t))?"estimate"===e.type?i({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:e.estimatedStart}):(t={mediaSeconds:n},(e=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,i=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*i)}(n,e.segment))&&(t.programDateTime=e.toISOString()),i(null,t)):i({message:"valid programTime was not found"}):i({message:"getProgramTime: playlist and time must be provided"})}function Eu(e){var t=e.programTime,i=e.playlist,n=e.retryCount,r=void 0===n?2:n,a=e.seekTo,s=e.pauseAfterSeek,o=void 0===s||s,u=e.tech,l=e.callback;if(!l)throw new Error("seekToProgramTime: callback must be provided");return"undefined"!=typeof t&&i&&a?i.endList||u.hasStarted_?function(e){if(!e.segments||0===e.segments.length)return!1;for(var t=0;t<e.segments.length;t++)if(!e.segments[t].dateTimeObject)return!1;return!0}(i)?(n=function(e,t){var i;try{i=new Date(e)}catch(e){return null}if(!t||!t.segments||0===t.segments.length)return null;if(i<(r=t.segments[0]).dateTimeObject)return null;for(var n=0;n<t.segments.length-1;n++){var r=t.segments[n];if(i<t.segments[n+1].dateTimeObject)break}var a,s=t.segments[t.segments.length-1],e=s.dateTimeObject,a=s.videoTimingInfo?(a=s.videoTimingInfo).transmuxedPresentationEnd-a.transmuxedPresentationStart-a.transmuxerPrependedSeconds:s.duration+.25*s.duration;return new Date(e.getTime()+1e3*a)<i?null:{segment:r=e<i?s:r,estimatedStart:r.videoTimingInfo?r.videoTimingInfo.transmuxedPresentationStart:fl.duration(t,t.mediaSequence+t.segments.indexOf(r)),type:r.videoTimingInfo?"accurate":"estimate"}}(t,i))?(s=n.segment,e=function(e,t){var i;try{n=new Date(e),i=new Date(t)}catch(e){}var n=n.getTime();return(i.getTime()-n)/1e3}(s.dateTimeObject,t),"estimate"===n.type?0===r?l({message:t+" is not buffered yet. Try again"}):(a(n.estimatedStart+e),void u.one("seeked",function(){Eu({programTime:t,playlist:i,retryCount:r-1,seekTo:a,pauseAfterSeek:o,tech:u,callback:l})})):(e=s.start+e,u.one("seeked",function(){return l(null,u.currentTime())}),o&&u.pause(),void a(e))):l({message:t+" was not found in the stream"}):l({message:"programDateTime tags must be provided in the manifest "+i.resolvedUri}):l({message:"player must be playing a live stream to start buffering"}):l({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"})}function ku(e,t){if(4===e.readyState)return t()}function Cu(e,t,r){function n(e,t,i,n){return t.abort(),o=!0,r(e,t,i,n)}function i(e,t){if(!o){if(e)return n(e,t,"",s);var i=t.responseText.substring(s&&s.byteLength||0,t.responseText.length);if(s=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];if((t=t.filter(function(e){return e&&(e.byteLength||e.length)&&"string"!=typeof e})).length<=1)return zs(t[0]);var n=t.reduce(function(e,t,i){return e+(t.byteLength||t.length)}
4716,0),r=new Uint8Array(n),a=0;return t.forEach(function(e){e=zs(e),r.set(e,a),a+=e.byteLength}),r}(s,Ks(i,!0)),a=a||Qs(s),s.length<10||a&&s.length<a+2)return ku(t,function(){return n(e,t,"",s)});i=Lo(s);return"ts"===i&&s.length<188||!i&&s.length<376?ku(t,function(){return n(e,t,"",s)}):n(null,t,i,s)}}var a,s=[],o=!1,u=t({uri:e,beforeSend:function(t){t.overrideMimeType("text/plain; charset=x-user-defined"),t.addEventListener("progress",function(e){return e.total,e.loaded,fu(t,null,{statusCode:t.status},i)})}},function(e,t){return fu(u,e,t,i)});return u}function Iu(e,t){if(!du(e,t))return!1;if(e.sidx&&t.sidx&&(e.sidx.offset!==t.sidx.offset||e.sidx.length!==t.sidx.length))return!1;if(!e.sidx&&t.sidx||e.sidx&&!t.sidx)return!1;if(e.segments&&!t.segments||!e.segments&&t.segments)return!1;if(!e.segments&&!t.segments)return!0;for(var i=0;i<e.segments.length;i++){var n=e.segments[i],r=t.segments[i];if(n.uri!==r.uri)return!1;if(n.byterange||r.byterange){n=n.byterange,r=r.byterange;if(n&&!r||!n&&r)return!1;if(n.offset!==r.offset||n.length!==r.length)return!1}}return!0}function xu(e,t){var i,n={};for(i in e){var r=e[i].sidx;if(r){var a=bs(r);if(!t[a])break;var s=t[a].sidxInfo;s=s,r=r,(Boolean(!s.map&&!r.map)||Boolean(s.map&&r.map&&s.map.byterange.offset===r.map.byterange.offset&&s.map.byterange.length===r.map.byterange.length))&&s.uri===r.uri&&s.byterange.offset===r.byterange.offset&&s.byterange.length===r.byterange.length&&(n[a]=t[a])}}return n}function Au(e){return e.on=e.addEventListener,e.off=e.removeEventListener,e}function Pu(i){var n=i.transmuxer,e=i.bytes,t=i.audioAppendStart,r=i.gopsToAlignWith,a=i.remux,s=i.onData,o=i.onTrackInfo,u=i.onAudioTimingInfo,l=i.onVideoTimingInfo,c=i.onVideoSegmentTimingInfo,d=i.onAudioSegmentTimingInfo,h=i.onId3,p=i.onCaptions,f=i.onDone,m=i.onEndedTimeline,g=i.onTransmuxerLog,y=i.isEndOfTimeline,v={buffer:[]},_=y;n.onmessage=function(e){var t;n.currentTransmux===i&&("data"===e.data.action&&function(e,t,i){var n=e.data.segment,r=n.type,a=n.initSegment,s=n.captions,o=n.captionStreams,u=n.metadata,l=n.videoFrameDtsTime,n=n.videoFramePtsTime;t.buffer.push({captions:s,captionStreams:o,metadata:u});e=e.data.segment.boxes||{data:e.data.segment.data},a={type:r,data:new Uint8Array(e.data,e.data.byteOffset,e.data.byteLength),initSegment:new Uint8Array(a.data,a.byteOffset,a.byteLength)};"undefined"!=typeof l&&(a.videoFrameDtsTime=l),"undefined"!=typeof n&&(a.videoFramePtsTime=n),i(a)}(e,v,s),"trackinfo"===e.data.action&&o(e.data.trackInfo),"gopInfo"===e.data.action&&(v.gopInfo=e.data.gopInfo),"audioTimingInfo"===e.data.action&&u(e.data.audioTimingInfo),"videoTimingInfo"===e.data.action&&l(e.data.videoTimingInfo),"videoSegmentTimingInfo"===e.data.action&&c(e.data.videoSegmentTimingInfo),"audioSegmentTimingInfo"===e.data.action&&d(e.data.audioSegmentTimingInfo),"id3Frame"===e.data.action&&h([e.data.id3Frame],e.data.id3Frame.dispatchType),"caption"===e.data.action&&p(e.data.caption),"endedtimeline"===e.data.action&&(_=!1,m()),"log"===e.data.action&&g(e.data.log),"transmuxed"===e.data.type&&(_||(n.onmessage=null,e=(t={transmuxedData:v,callback:f}).transmuxedData,t=t.callback,e.buffer=[],t(e),El(n))))},t&&n.postMessage({action:"setAudioAppendStart",appendStart:t}),Array.isArray(r)&&n.postMessage({action:"alignGopsWith",gopsToAlignWith:r}),"undefined"!=typeof a&&n.postMessage({action:"setRemux",remux:a}),e.byteLength&&(r=e instanceof ArrayBuffer?e:e.buffer,a=e instanceof ArrayBuffer?0:e.byteOffset,n.postMessage({action:"push",data:r,byteOffset:a,byteLength:e.byteLength},[r])),y&&n.postMessage({action:"endTimeline"}),n.postMessage({action:"flush"})}function Lu(e,t){e.postMessage({action:t}),El(e)}function Du(e,t){if(!t.currentTransmux)return t.currentTransmux=e,Lu(t,e),0;t.transmuxQueue.push(Lu.bind(null,t,e))}function Ou(e){if(!e.transmuxer.currentTransmux)return e.transmuxer.currentTransmux=e,void Pu(e);e.transmuxer.transmuxQueue.push(e)}function Ru(i){var n=i.transmuxer,r=i.endAction||i.action,a=i.callback,e=g({},i,{endAction:null,transmuxer:null,callback:null}),t=function e(t){t.data.action===r&&(n.removeEventListener("message",e),t.data.data&&(t.data.data=new Uint8Array(t.data.data,i.byteOffset||0,i.byteLength||t.data.data.byteLength),i.data&&(i.data=t.data.data)),a(t.data))};n.addEventListener("message",t),i.data?(t=i.data instanceof ArrayBuffer,e.byteOffset=t?0:i.data.byteOffset,e.byteLength=i.data.byteLength,t=[t?i.data:i.data.buffer],n.postMessage(e,t)):n.postMessage(e)}function Mu(e){e.forEach(function(e){e.abort()})}function Nu(e,t){return t.timedout?{status:t.status,message:"HLS request timed-out at URL: "+t.uri,code:xl,xhr:t}:t.aborted?{status:t.status,message:"HLS request aborted at URL: "+t.uri,code:Al,xhr:t}:e?{status:t.status,message:"HLS request errored at URL: "+t.uri,code:Il,xhr:t}:"arraybuffer"===t.responseType&&0===t.response.byteLength?{status:t.status,message:"Empty HLS response at URL: "+t.uri,code:Il,xhr:t}:null}function Uu(a,s,o){return function(e,t){var i=t.response,e=Nu(e,t);if(e)return o(e,a);if(16!==i.byteLength)return o({status:t.status,message:"Invalid HLS key at URL: "+t.uri,code:Il,xhr:t},a);for(var i=new DataView(i),n=new Uint32Array([i.getUint32(0),i.getUint32(4),i.getUint32(8),i.getUint32(12)]),r=0;r<s.length;r++)s[r].bytes=n;return o(null,a)}}function Bu(i,n){var e=Lo(i.map.bytes);if("mp4"!==e){var t=i.map.resolvedUri||i.map.uri;return n({internal:!0,message:"Found unsupported "+(e||"unknown")+" container for initialization segment at URL: "+t,code:Il})}Ru({action:"probeMp4Tracks",data:i.map.bytes,transmuxer:i.transmuxer,callback:function(e){var t=e.tracks,e=e.data;return i.map.bytes=e,t.forEach(function(e){i.map.tracks=i.map.tracks||{},i.map.tracks[e.type]||"number"==typeof(i.map.tracks[e.type]=e).id&&e.timescale&&(i.map.timescales=i.map.timescales||{},i.map.timescales[e.id]=e.timescale)}),n(null)}})}function Fu(e){var i=e.segment,n=e.finishProcessingFn,r=e.responseType;return function(e,t){e=Nu(e,t);if(e)return n(e,i);e="arraybuffer"!==r&&t.responseText?function(e){for(var t=new Uint8Array(new ArrayBuffer(e.length)),i=0;i<e.length;i++)t[i]=e.charCodeAt(i);return t.buffer}(t.responseText.substring(i.lastReachedChar||0)):t.response;return i.stats={bandwidth:(t=t).bandwidth,bytesReceived:t.bytesReceived||0,roundTripTime:t.roundTripTime||0},i.key?i.encryptedBytes=new Uint8Array(e):i.bytes=new Uint8Array(e),n(null,i)}}function ju(e){var i=e.segment,t=e.bytes,n=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,e=i.map&&i.map.tracks||{},f=Boolean(e.audio&&e.video),m=r.bind(null,i,"audio","start"),g=r.bind(null,i,"audio","end"),y=r.bind(null,i,"video","start"),v=r.bind(null,i,"video","end");Ru({action:"probeTs",transmuxer:i.transmuxer,data:t,baseStartTime:i.baseStartTime,callback:function(e){i.bytes=t=e.data;e=e.result;e&&(n(i,{hasAudio:e.hasAudio,hasVideo:e.hasVideo,isMuxed:f}),n=null,e.hasAudio&&!f&&m(e.audioStart),e.hasVideo&&y(e.videoStart),y=m=null),Ou({bytes:t,transmuxer:i.transmuxer,audioAppendStart:i.audioAppendStart,gopsToAlignWith:i.gopsToAlignWith,remux:f,onData:function(e){e.type="combined"===e.type?"video":e.type,d(i,e)},onTrackInfo:function(e){n&&(f&&(e.isMuxed=!0),n(i,e))},onAudioTimingInfo:function(e){m&&"undefined"!=typeof e.start&&(m(e.start),m=null),g&&"undefined"!=typeof e.end&&g(e.end)},onVideoTimingInfo:function(e){y&&"undefined"!=typeof e.start&&(y(e.start),y=null),v&&"undefined"!=typeof e.end&&v(e.end)},onVideoSegmentTimingInfo:function(e){a(e)},onAudioSegmentTimingInfo:function(e){s(e)},onId3:function(e,t){o(i,e,t)},onCaptions:function(e){u(i,[e])},isEndOfTimeline:l,onEndedTimeline:function(){c()},onTransmuxerLog:p,onDone:function(e){h&&(e.type="combined"===e.type?"video":e.type,h(null,i,e))}})}})}function Hu(e){var i=e.segment,n=e.bytes,t=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,f=new
4716Uint8Array(n);if(0<Js(f,["moof"]).length){i.isFmp4=!0;var m=i.map.tracks,g={isFmp4:!0,hasVideo:!!m.video,hasAudio:!!m.audio};m.audio&&m.audio.codec&&"enca"!==m.audio.codec&&(g.audioCodec=m.audio.codec),m.video&&m.video.codec&&"encv"!==m.video.codec&&(g.videoCodec=m.video.codec),m.video&&m.audio&&(g.isMuxed=!0),t(i,g);var y=function(e){d(i,{data:f,type:g.hasAudio&&!g.isMuxed?"audio":"video"}),e&&e.length&&u(i,e),h(null,i,{})};Ru({action:"probeMp4StartTime",timescales:i.map.timescales,data:f,transmuxer:i.transmuxer,callback:function(e){var t=e.data,e=e.startTime;n=t.buffer,i.bytes=f=t,g.hasAudio&&!g.isMuxed&&r(i,"audio","start",e),g.hasVideo&&r(i,"video","start",e),m.video&&t.byteLength&&i.transmuxer?Ru({action:"pushMp4Captions",endAction:"mp4Captions",transmuxer:i.transmuxer,data:f,timescales:i.map.timescales,trackIds:[m.video.id],callback:function(e){n=e.data.buffer,i.bytes=f=e.data,e.logs.forEach(function(e){p(tr.mergeOptions(e,{stream:"mp4CaptionParser"}))}),y(e.captions)}}):y()}})}else if(i.transmuxer){if("undefined"==typeof i.container&&(i.container=Lo(f)),"ts"!==i.container&&"aac"!==i.container)return t(i,{hasAudio:!1,hasVideo:!1}),h(null,i,{}),0;ju({segment:i,bytes:n,trackInfoFn:t,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:l,endedTimelineFn:c,dataFn:d,doneFn:h,onTransmuxerLog:p})}else h(null,i,{})}function qu(e,i){var n=e.id,t=e.key,r=e.encryptedBytes,a=e.decryptionWorker,e=function e(t){t.data.source===n&&(a.removeEventListener("message",e),t=t.data.decrypted,i(new Uint8Array(t.bytes,t.byteOffset,t.byteLength)))};a.addEventListener("message",e),e=t.bytes.slice?t.bytes.slice():new Uint32Array(Array.prototype.slice.call(t.bytes)),a.postMessage(_u({source:n,encrypted:r,key:e,iv:t.iv}),[r.buffer,e.buffer])}function Vu(e){var i=e.activeXhrs,m=e.decryptionWorker,g=e.trackInfoFn,y=e.timingInfoFn,v=e.videoSegmentTimingInfoFn,_=e.audioSegmentTimingInfoFn,b=e.id3Fn,T=e.captionsFn,S=e.isEndOfTimeline,w=e.endedTimelineFn,E=e.dataFn,k=e.doneFn,C=e.onTransmuxerLog,n=0,r=!1;return function(e,f){if(!r){if(e)return r=!0,Mu(i),k(e,f);if((n+=1)===i.length){var t=function(){if(f.encryptedBytes)return t=(e={decryptionWorker:m,segment:f,trackInfoFn:g,timingInfoFn:y,videoSegmentTimingInfoFn:v,audioSegmentTimingInfoFn:_,id3Fn:b,captionsFn:T,isEndOfTimeline:S,endedTimelineFn:w,dataFn:E,doneFn:k,onTransmuxerLog:C}).decryptionWorker,i=e.segment,n=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,void qu({id:i.requestId,key:i.key,encryptedBytes:i.encryptedBytes,decryptionWorker:t},function(e){i.bytes=e,Hu({segment:i,bytes:i.bytes,trackInfoFn:n,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:l,endedTimelineFn:c,dataFn:d,doneFn:h,onTransmuxerLog:p})});var e,t,i,n,r,a,s,o,u,l,c,d,h,p;Hu({segment:f,bytes:f.bytes,trackInfoFn:g,timingInfoFn:y,videoSegmentTimingInfoFn:v,audioSegmentTimingInfoFn:_,id3Fn:b,captionsFn:T,isEndOfTimeline:S,endedTimelineFn:w,dataFn:E,doneFn:k,onTransmuxerLog:C})};if(f.endOfAllRequests=Date.now(),f.map&&f.map.encryptedBytes&&!f.map.bytes)return qu({decryptionWorker:m,id:f.requestId+"-init",encryptedBytes:f.map.encryptedBytes,key:f.map.key},function(e){f.map.bytes=e,Bu(f,function(e){return e?(Mu(i),k(e,f)):void t()})});t()}}}}function Wu(e){var n=e.segment,r=e.progressFn;return e.trackInfoFn,e.timingInfoFn,e.videoSegmentTimingInfoFn,e.audioSegmentTimingInfoFn,e.id3Fn,e.captionsFn,e.isEndOfTimeline,e.endedTimelineFn,e.dataFn,function(e){var t,i=e.target;if(!i.aborted)return n.stats=tr.mergeOptions(n.stats,(i=(t=e).target,(i={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-i.requestTime||0}).bytesReceived=t.loaded,i.bandwidth=Math.floor(i.bytesReceived/i.roundTripTime*8*1e3),i)),!n.stats.firstBytesReceivedAt&&n.stats.bytesReceived&&(n.stats.firstBytesReceivedAt=Date.now()),r(e,n)}}function Gu(e){var t,i,n,r=e.xhr,a=e.xhrOptions,s=e.decryptionWorker,o=e.segment,u=e.abortFn,l=e.progressFn,c=e.trackInfoFn,d=e.timingInfoFn,h=e.videoSegmentTimingInfoFn,p=e.audioSegmentTimingInfoFn,f=e.id3Fn,m=e.captionsFn,g=e.isEndOfTimeline,y=e.endedTimelineFn,v=e.dataFn,_=e.doneFn,e=e.onTransmuxerLog,b=[],_=Vu({activeXhrs:b,decryptionWorker:s,trackInfoFn:c,timingInfoFn:d,videoSegmentTimingInfoFn:h,audioSegmentTimingInfoFn:p,id3Fn:f,captionsFn:m,isEndOfTimeline:g,endedT
4716imelineFn:y,dataFn:v,doneFn:_,onTransmuxerLog:e});o.key&&!o.key.bytes&&(e=[o.key],o.map&&!o.map.bytes&&o.map.key&&o.map.key.resolvedUri===o.key.resolvedUri&&e.push(o.map.key),e=r(tr.mergeOptions(a,{uri:o.key.resolvedUri,responseType:"arraybuffer"}),Uu(o,e,_)),b.push(e)),o.map&&!o.map.bytes&&(!o.map.key||o.key&&o.key.resolvedUri===o.map.key.resolvedUri||(t=r(tr.mergeOptions(a,{uri:o.map.key.resolvedUri,responseType:"arraybuffer"}),Uu(o,[o.map.key],_)),b.push(t)),t=r(tr.mergeOptions(a,{uri:o.map.resolvedUri,responseType:"arraybuffer",headers:gu(o.map)}),(i=(t={segment:o,finishProcessingFn:_}).segment,n=t.finishProcessingFn,function(e,t){e=Nu(e,t);if(e)return n(e,i);e=new Uint8Array(t.response);if(i.map.key)return i.map.encryptedBytes=e,n(null,i);i.map.bytes=e,Bu(i,function(e){return e?(e.xhr=t,e.status=t.status,n(e,i)):void n(null,i)})})),b.push(t)),a=tr.mergeOptions(a,{uri:o.part&&o.part.resolvedUri||o.resolvedUri,responseType:"arraybuffer",headers:gu(o)}),(a=r(a,Fu({segment:o,finishProcessingFn:_,responseType:a.responseType}))).addEventListener("progress",Wu({segment:o,progressFn:l,trackInfoFn:c,timingInfoFn:d,videoSegmentTimingInfoFn:h,audioSegmentTimingInfoFn:p,id3Fn:f,captionsFn:m,isEndOfTimeline:g,endedTimelineFn:y,dataFn:v})),b.push(a);var T={};return b.forEach(function(e){var t,i;e.addEventListener("loadend",(t=(e={loadendState:T,abortFn:u}).loadendState,i=e.abortFn,function(e){e.target.aborted&&i&&!t.calledAbortFn&&(i(),t.calledAbortFn=!0)}))}),function(){return Mu(b)}}function zu(e,t){return t=t.attributes||{},e&&e.mediaGroups&&e.mediaGroups.AUDIO&&t.AUDIO&&e.mediaGroups.AUDIO[t.AUDIO]}function Xu(e){var n={};return e.forEach(function(e){var t=e.mediaType,i=e.type,e=e.details;n[t]=n[t]||[],n[t].push(hr(""+i+e))}),Object.keys(n).forEach(function(e){return 1<n[e].length?(Pl("multiple "+e+" codecs found as attributes: "+n[e].join(", ")+". Setting playlist codecs to null so that we wait for mux.js to probe segments for real codecs."),void(n[e]=null)):void(n[e]=n[e][0])}),n}function Ku(e){var t=0;return e.audio&&t++,e.video&&t++,t}function Yu(e,t){var i,n=t.attributes||{},r=Xu(function(e){e=e.attributes||{};if(e.CODECS)return pr(e.CODECS)}(t)||[]);return zu(e,t)&&!r.audio&&!function(e,t){if(!zu(e,t))return!0;var i,t=t.attributes||{},n=e.mediaGroups.AUDIO[t.AUDIO];for(i in n)if(!n[i].uri&&!n[i].playlists)return!0;return!1}(e,t)&&(i=Xu(function(e,t){if(!e.mediaGroups.AUDIO||!t)return null;var i,n=e.mediaGroups.AUDIO[t];if(!n)return null;for(i in n){var r=n[i];if(r.default&&r.playlists)return pr(r.playlists[0].attributes.CODECS)}return null}(e,n.AUDIO)||[])).audio&&(r.audio=i.audio),r}function Qu(e){if(e&&e.playlist){var t=e.playlist;return JSON.stringify({id:t.id,bandwidth:e.bandwidth,width:e.width,height:e.height,codecs:t.attributes&&t.attributes.CODECS||""})}}function $u(e,t){return(e=e&&window.getComputedStyle(e))?e[t]:""}function Ju(e,n){var r=e.slice();e.sort(function(e,t){var i=n(e,t);return 0===i?r.indexOf(e)-r.indexOf(t):i})}function Zu(e,t){var i,n;return(i=(i=e.attributes.BANDWIDTH?e.attributes.BANDWIDTH:i)||window.Number.MAX_VALUE)-(n=(n=t.attributes.BANDWIDTH?t.attributes.BANDWIDTH:n)||window.Number.MAX_VALUE)}function el(e,t,i,n,r,a){if(e){var s={bandwidth:t,width:i,height:n,limitRenditionByPlayerDimensions:r},o=e.playlists;fl.isAudioOnly(e)&&(o=a.getAudioTrackPlaylists_(),s.audioOnly=!0);var u=o.map(function(e){var t=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height,n=e.attributes&&e.attributes.BANDWIDTH;return{bandwidth:n||window.Number.MAX_VALUE,width:t,height:i,playlist:e}});Ju(u,function(e,t){return e.bandwidth-t.bandwidth});var l=(u=u.filter(function(e){return!fl.isIncompatible(e.playlist)})).filter(function(e){return fl.isEnabled(e.playlist)}),e=(l=!l.length?u.filter(function(e){return!fl.isDisabled(e.playlist)}):l).filter(function(e){return e.bandwidth*Sl.BANDWIDTH_VARIANCE<t}),c=e[e.length-1],o=e.filter(function(e){return e.bandwidth===c.bandwidth})[0];if(!1===r){var d=o||l[0]||u[0];if(d&&d.playlist){r=o?"bandwidthBestRep":"sortedPlaylistReps";return l[0]&&(r="enabledPlaylistReps"),Ll("choosing "+Qu(d)+" using "+r+" with options",s),d.playlist}return Ll("could not choose a playlist with options",s),null}d=e.filter(function(e){return e.width&&e.height});Ju(d,function(e,t){return e.width-t.width});var h,p,f,e=d.filter(function(e){return e.width===i&&e.height===n}),c=e[e.length-1],e=e.filter(function(e){return e.bandwidth===c.bandwidth})[0];e||(p=(h=d.filter(function(e){return e.width>i||e.height>n})).filter(function(e){return e.width===h[0].width&&e.height===h[0].height}),c=p[p.length-1],p=p.filter(function(e){return e.bandwidth===c.bandwidth})[0]),a.experimentalLeastPixelDiffSelector&&(m=d.map(function(e){return e.pixelDiff=Math.abs(e.width-i)+Math.abs(e.height-n),e}),Ju(m,function(e,t){return e.pixelDiff===t.pixelDiff?t.bandwidth-e.bandwidth:e.pixelDiff-t.pixelDiff}),f=m[0]);var m=f||p||e||o||l[0]||u[0];if(m&&m.playlist){u="sortedPlaylistReps";return f?u="leastPixelDiffRep":p?u="resolutionPlusOneRep":e?u="resolutionBestRep":o?u="bandwidthBestRep":l[0]&&(u="enabledPlaylistReps"),Ll("choosing "+Qu(m)+" using "+u+" with options",s),m.playlist}return Ll("could not choose a playlist with options",s),null}}function tl(e){var t=e.inbandTextTracks,i=e.metadataArray,r=e.timestampOffset,n=e.videoDuration;if(i){var a=window.WebKitDataCue||window.VTTCue,s=t.metadataTrack_;if(s&&(i.forEach(function(e){var n=e.cueTime+r;!("number"!=typeof n||window.isNaN(n)||n<0)&&n<1/0&&e.frames.forEac
4716h(function(e){var t,i=new a(n,n,e.value||e.url||e.data||"");i.frame=e,i.value=e,t=i,Object.defineProperties(t.frame,{id:{get:function(){return tr.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),t.value.key}},value:{get:function(){return tr.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),t.value.data}},privateData:{get:function(){return tr.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),t.value.data}}}),s.addCue(i)})}),s.cues&&s.cues.length)){for(var o=s.cues,u=[],l=0;l<o.length;l++)o[l]&&u.push(o[l]);var c=u.reduce(function(e,t){var i=e[t.startTime]||[];return i.push(t),e[t.startTime]=i,e},{}),d=Object.keys(c).sort(function(e,t){return Number(e)-Number(t)});d.forEach(function(e,t){var e=c[e],i=Number(d[t+1])||n;e.forEach(function(e){e.endTime=i})})}}}function il(e,t,i){var n,r;if(i&&i.cues)for(n=i.cues.length;n--;)(r=i.cues[n]).startTime>=e&&r.endTime<=t&&i.removeCue(r)}function nl(e){return"number"==typeof e&&isFinite(e)}function rl(e){var t=e.startOfSegment,i=e.duration,n=e.segment,r=e.part,a=e.playlist,s=a.mediaSequence,o=a.id,u=a.segments,l=e.mediaIndex,c=e.partIndex,d=e.timeline,h=(void 0===u?[]:u).length-1,p="mediaIndex/partIndex increment";return e.getMediaInfoForTime?p="getMediaInfoForTime ("+e.getMediaInfoForTime+")":e.isSyncRequest&&(p="getSyncSegmentCandidate (isSyncRequest)"),e.independent&&(p+=" with independent "+e.independent),a="number"==typeof c,u=e.segment.uri?"segment":"pre-segment",e=a?Wo({preloadSegment:n})-1:0,u+" ["+(s+l)+"/"+(s+h)+"]"+(a?" part ["+c+"/"+e+"]":"")+" segment start/end ["+n.start+" => "+n.end+"]"+(a?" part start/end ["+r.start+" => "+r.end+"]":"")+" startOfSegment ["+t+"] duration ["+i+"] timeline ["+d+"] selected by ["+p+"] playlist ["+o+"]"}function al(e){return e+"TimingInfo"}function sl(e){var t=e.timelineChangeController,i=e.currentTimeline,n=e.segmentTimeline,r=e.loaderType,e=e.audioDisabled;if(i!==n){if("audio"===r){i=t.lastTimelineChange({type:"main"});return!i||i.to!==n}if("main"===r&&e){t=t.pendingTimelineChange({type:"audio"});return t&&t.to===n?!1:!0}}}function ol(e){var t=e.segmentDuration,e=e.maxDuration;return!!t&&Math.round(t)>e+hl}function ul(e,t){if("hls"!==t)return null;var n,r,i=(n={audioTimingInfo:e.audioTimingInfo,videoTimingInfo:e.videoTimingInfo},r=0,["video","audio"].forEach(function(e){var t,i=n[e+"TimingInfo"];i&&(e=i.start,i=i.end,"bigint"==typeof e||"bigint"==typeof i?t=window.BigInt(i)-window.BigInt(e):"number"==typeof e&&"number"==typeof i&&(t=i-e),"undefined"!=typeof t&&r<t&&(r=t))}),r="bigint"==typeof r&&r<Number.MAX_SAFE_INTEGER?Number(r):r);if(!i)return null;var a=e.playlist.targetDuration,s=ol({segmentDuration:i,maxDuration:2*a}),t=ol({segmentDuration:i,maxDuration:a}),a="Segment with index "+e.mediaIndex+" from playlist "+e.playlist.id+" has a duration of "+i+" when the reported duration is "+e.duration+" and the target duration is "+a+". For HLS content, a duration in excess of the target duration may result in playback issues. See the HLS specification section on EXT-X-TARGETDURATION for more details: https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.3.1";return s||t?{severity:s?"warn":"info",message:a}:null}var ll=Ao,cl=9e4,dl=ir,hl=1/30,pl=tr.createTimeRange,fl={liveEdgeDelay:Go,duration:Xo,seekable:function(e,t,i){var n=t||0,i=Yo(e,t,!0,i);return null===i?pl():pl(n,i)},getMediaInfoForTime:function(e){for(var t=e.playlist,i=e.currentTime,n=e.startingSegmentIndex,r=e.startingPartIndex,a=e.startTime,s=e.experimentalExactManifestTimings,o=i-a,u=qo(t),l=0,c=0;c<u.length;c++){var d=u[c];if(n===d.segmentIndex&&("number"!=typeof r||"number"!=typeof d.partIndex||r===d.partIndex)){l=c;break}}if(o<0){if(0<l)for(var h=l-1;0<=h;h--){var p=u[h];if(o+=p.duration,s){if(o<0)continue}else if(o+hl<=0)continue;return{partIndex:p.partIndex,segmentIndex:p.segmentIndex,startTime:a-Ko({defaultDuration:t.targetDuration,durationList:u,startIndex:l,endIndex:h})}}return{partIndex:u[0]&&u[0].partIndex||null,segmentIndex:u[0]&&u[0].segmentIndex||0,startTime:i}}if(l<0){for(var f=l;f<0;f++)if((o-=t.targetDuration)<0)return{partIndex:u[0]&&u[0].partIndex||null,segmentIndex:u[0]&&u[0].segmentIndex||0,startTime:i};l=0}for(var m=l;m<u.length;m++){var g=u[m];
4716if(o-=g.duration,s){if(0<o)continue}else if(0<=o-hl)continue;return{partIndex:g.partIndex,segmentIndex:g.segmentIndex,startTime:a+Ko({defaultDuration:t.targetDuration,durationList:u,startIndex:l,endIndex:m})}}return{segmentIndex:u[u.length-1].segmentIndex,partIndex:u[u.length-1].partIndex,startTime:i}},isEnabled:Jo,isDisabled:function(e){return e.disabled},isBlacklisted:Qo,isIncompatible:$o,playlistEnd:Yo,isAes:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].key)return!0;return!1},hasAttribute:Zo,estimateSegmentRequestTime:function(e,t,i,n){return Zo("BANDWIDTH",i)?(e*i.attributes.BANDWIDTH-8*(n=void 0===n?0:n))/t:NaN},isLowestEnabledRendition:eu,isAudioOnly:nu,playlistMatch:tu,segmentDurationWithParts:Ho},ml=tr.log,gl=tr.mergeOptions,W=tr.EventTarget,yl=function(a){function e(e,t,i){var n;if(void 0===i&&(i={}),n=a.call(this)||this,!e)throw new Error("A non-empty playlist URL or object is required");n.logger_=Oo("PlaylistLoader");var r=i.withCredentials,r=void 0!==r&&r,i=i.handleManifestRedirects,i=void 0!==i&&i;n.src=e,n.vhs_=t,n.withCredentials=r,n.handleManifestRedirects=i;t=t.options_;return n.customTagParsers=t&&t.customTagParsers||[],n.customTagMappers=t&&t.customTagMappers||[],n.experimentalLLHLS=t&&t.experimentalLLHLS||!1,tr.browser.IE_VERSION&&(n.experimentalLLHLS=!1),n.state="HAVE_NOTHING",n.handleMediaupdatetimeout_=n.handleMediaupdatetimeout_.bind(ft(n)),n.on("mediaupdatetimeout",n.handleMediaupdatetimeout_),n}mt(e,a);var t=e.prototype;return t.handleMediaupdatetimeout_=function(){var e,t,i=this;"HAVE_METADATA"===this.state&&(e=this.media(),t=dl(this.master.uri,e.uri),this.experimentalLLHLS&&(t=function(e,t){if(t.endList||!t.serverControl)return e;var i,n,r,a,s={};return t.serverControl.canBlockReload&&(r=t.preloadSegment,i=t.mediaSequence+t.segments.length,r&&(n=r.parts||[],-1<(r=Wo(t)-1)&&r!=n.length-1&&(s._HLS_part=r),(-1<r||n.length)&&i--),s._HLS_msn=i),t.serverControl&&t.serverControl.canSkipUntil&&(s._HLS_skip=t.serverControl.canSkipDateranges?"v2":"YES"),Object.keys(s).length&&(a=new window.URL(e),["_HLS_skip","_HLS_msn","_HLS_part"].forEach(function(e){s.hasOwnProperty(e)&&a.searchParams.set(e,s[e])}),e=a.toString()),e}(t,e)),this.state="HAVE_CURRENT_METADATA",this.request=this.vhs_.xhr({uri:t,withCredentials:this.withCredentials},function(e,t){if(i.request)return e?i.playlistRequestError(i.request,i.media(),"HAVE_METADATA"):void i.haveMetadata({playlistString:i.request.responseText,url:i.media().uri,id:i.media().id})}))},t.playlistRequestError=function(e,t,i){var n=t.uri,t=t.id;this.request=null,i&&(this.state=i),this.error={playlist:this.master.playlists[t],status:e.status,message:"HLS playlist request error at URL: "+n+".",responseText:e.responseText,code:500<=e.status?4:2},this.trigger("error")},t.parseManifest_=function(e){var t=this,i=e.url;return function(e){var t=e.onwarn,i=e.oninfo,n=e.manifestString,r=e.customTagParsers,a=void 0===r?[]:r,r=e.customTagMappers,r=void 0===r?[]:r,e=e.experimentalLLHLS,s=new Sr;t&&s.on("warn",t),i&&s.on("info",i),a.forEach(function(e){return s.addParser(e)}),r.forEach(function(e){return s.addTagMapper(e)}),s.push(n),s.end();var o=s.manifest;e||(["preloadSegment","skip","serverControl","renditionReports","partInf","partTargetDuration"].forEach(function(e){o.hasOwnProperty(e)&&delete o[e]}),o.segments&&o.segments.forEach(function(t){["parts","preloadHints"].forEach(function(e){t.hasOwnProperty(e)&&delete t[e]})})),o.targetDuration||(u=10,o.segments&&o.segments.length&&(u=o.segments.reduce(function(e,t){return Math.max(e,t.duration)},0)),t&&t("manifest has no targetDuration defaulting to "+u),o.targetDuration=u);var u=Vo(o);return u.length&&!o.partTargetDuration&&(u=u.reduce(function(e,t){return Math.max(e,t.duration)},0),t&&(t("manifest has no partTargetDuration defaulting to "+u),ml.error("LL-HLS manifest has parts but lacks required #EXT-X-PART-INF:PART-TARGET value. See https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-09#section-4.4.3.7. Playback is not guaranteed.")),o.partTargetDuration=u),o}({onwarn:function(e){e=e.message;return t.logger_("m3u8-parser warn for "+i+": "+e)},oninfo:function(e){e=e.message;return t.logger_("m3u8-parser info for "+i+": "+e)},manifestString:e.manifestString,customTagParsers:this.customTagParsers,customTagMappers:this.customTagMappers,experimentalLLHLS:this.experimentalLLHLS})},t.haveMetadata=function(e){var t=e.playlistString,i=e.playlistOb
4716ject,n=e.url,e=e.id;this.request=null,this.state="HAVE_METADATA";t=i||this.parseManifest_({url:n,manifestString:t});t.lastRequest=Date.now(),su({playlist:t,uri:n,id:e});n=hu(this.master,t);this.targetDuration=t.partTargetDuration||t.targetDuration,this.pendingMedia_=null,n?(this.master=n,this.media_=this.master.playlists[e]):this.trigger("playlistunchanged"),this.updateMediaUpdateTimeout_(pu(this.media(),!!n)),this.trigger("loadedplaylist")},t.dispose=function(){this.trigger("dispose"),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),window.clearTimeout(this.finalRenditionTimeout),this.off()},t.stopRequest=function(){var e;this.request&&(e=this.request,this.request=null,e.onreadystatechange=null,e.abort())},t.media=function(i,e){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}if(window.clearTimeout(this.finalRenditionTimeout),e){var t=(i.partTargetDuration||i.targetDuration)/2*1e3||5e3;this.finalRenditionTimeout=window.setTimeout(this.media.bind(this,i,!1),t)}else{var r=this.state,e=!this.media_||i.id!==this.media_.id,t=this.master.playlists[i.id];if(t&&t.endList||i.endList&&i.segments.length)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=i,void(e&&(this.trigger("mediachanging"),"HAVE_MASTER"===r?this.trigger("loadedmetadata"):this.trigger("mediachange")));if(this.updateMediaUpdateTimeout_(pu(i,!0)),e){if(this.state="SWITCHING_MEDIA",this.request){if(i.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.pendingMedia_=i,this.request=this.vhs_.xhr({uri:i.resolvedUri,withCredentials:this.withCredentials},function(e,t){if(n.request){if(i.lastRequest=Date.now(),i.resolvedUri=Do(n.handleManifestRedirects,i.resolvedUri,t),e)return n.playlistRequestError(n.request,i,r);n.haveMetadata({playlistString:t.responseText,url:i.uri,id:i.id}),"HAVE_MASTER"===r?n.trigger("loadedmetadata"):n.trigger("mediachange")}})}}},t.pause=function(){this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.stopRequest(),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")},t.load=function(e){var t=this;this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null);var i=this.media();e?(e=i?(i.partTargetDuration||i.targetDuration)/2*1e3:5e3,this.mediaUpdateTimeout=window.setTimeout(function(){t.mediaUpdateTimeout=null,t.load()},e)):this.started?i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()},t.updateMediaUpdateTimeout_=function(e){var t=this;this.mediaUpdateTimeout&&(window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.media()&&!this.media().endList&&(this.mediaUpdateTimeout=window.setTimeout(function(){t.mediaUpdateTimeout=null,t.trigger("mediaupdatetimeout"),t.updateMediaUpdateTimeout_(e)},e))},t.start=function(){var i=this;
4716if(this.started=!0,"object"==typeof this.src)return this.src.uri||(this.src.uri=window.location.href),this.src.resolvedUri=this.src.uri,void setTimeout(function(){i.setupInitialPlaylist(i.src)},0);this.request=this.vhs_.xhr({uri:this.src,withCredentials:this.withCredentials},function(e,t){if(i.request){if(i.request=null,e)return i.error={status:t.status,message:"HLS playlist request error at URL: "+i.src+".",responseText:t.responseText,code:2},"HAVE_NOTHING"===i.state&&(i.started=!1),i.trigger("error");i.src=Do(i.handleManifestRedirects,i.src,t);t=i.parseManifest_({manifestString:t.responseText,url:i.src});i.setupInitialPlaylist(t)}})},t.srcUri=function(){return"string"==typeof this.src?this.src:this.src.uri},t.setupInitialPlaylist=function(e){if(this.state="HAVE_MASTER",e.playlists)return this.master=e,ou(this.master,this.srcUri()),e.playlists.forEach(function(t){t.segments=cu(t),t.segments.forEach(function(e){lu(e,t.resolvedUri)})}),this.trigger("loadedplaylist"),void(this.request||this.media(this.master.playlists[0]));var t,i,n,r=this.srcUri()||window.location.href;this.master=(i=ru(0,t=r),(n={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:window.location.href,resolvedUri:window.location.href,playlists:[{uri:t,id:i,resolvedUri:t,attributes:{}}]}).playlists[i]=n.playlists[0],n.playlists[t]=n.playlists[0],n),this.haveMetadata({playlistObject:e,url:r,id:this.master.playlists[0].id}),this.trigger("loadedmetadata")},e}(W),vl=tr.xhr,_l=tr.mergeOptions,zt=Object.freeze({__proto__:null,createTransferableMessage:_u,initSegmentId:bu,segmentKeyId:Tu,hexDump:Su,tagDump:function(e){e=e.bytes;return Su(e)},textRanges:function(e){for(var t,i,n="",r=0;r<e.length;r++)n+=(i=r,(t=e).start(i)+"-"+t.end(i)+" ");return n}}),ar=tr.EventTarget,bl=tr.mergeOptions,Tl=function(a){function e(e,t,i,n){var r;void 0===i&&(i={}),(r=a.call(this)||this).masterPlaylistLoader_=n||ft(r),n||(r.isMaster_=!0);n=i.withCredentials,n=void 0!==n&&n,i=i.handleManifestRedirects,i=void 0!==i&&i;if(r.vhs_=t,r.withCredentials=n,r.handleManifestRedirects=i,!e)throw new Error("A non-empty playlist URL or object is required");return r.on("minimumUpdatePeriod",function(){r.refreshXml_()}),r.on("mediaupdatetimeout",function(){r.refreshMedia_(r.media().id)}),r.state="HAVE_NOTHING",r.loadedPlaylists_={},r.logger_=Oo("DashPlaylistLoader"),r.isMaster_?(r.masterPlaylistLoader_.srcUrl=e,r.masterPlaylistLoader_.sidxMapping_={}):r.childPlaylist_=e,r}mt(e,a);var t=e.prototype;return t.requestErrored_=function(e,t,i){return!this.request||(this.request=null,e?(this.error="object"!=typeof e||e instanceof Error?{status:t.status,message:"DASH request error at URL: "+t.uri,response:t.response,code:2}:e,i&&(this.state=i),this.trigger("error"),!0):void 0)},t.addSidxSegments_=function(a,n,r){var s,o,u=this,l=a.sidx&&bs(a.sidx);a.sidx&&l&&!this.masterPlaylistLoader_.sidxMapping_[l]?(s=Do(this.handleManifestRedirects,a.sidx.resolvedUri),o=function(e,t){if(!u.requestErrored_(e,t,n)){var i,e=u.masterPlaylistLoader_.sidxMapping_;try{i=_o(zs(t.response).subarray(8))}catch(e){return void u.requestErrored_(e,t,n)}return e[l]={sidxInfo:a.sidx,sidx:i},ms(a,i,a.sidx.resolvedUri),r(!0)}},this.request=Cu(s,this.vhs_.xhr,function(e,t,i,n){if(e)return o(e,t);if(!i||"mp4"!==i)return o({status:t.status,message:"Unsupported "+(i||"unknown")+" container type for sidx segment at URL: "+s,response:"",playlist:a,internal:!0,blacklistDuration:1/0,code:2},t);var r=a.sidx.byterange,i=r.offset,r=r.length;if(n.length>=r+i)return o(e,{response:n.subarray(i,i+r),status:t.status,uri:t.uri});u.request=u.vhs_.xhr({uri:s,responseType:"arraybuffer",headers:gu({byterange:a.sidx.byterange})},o)})):this.mediaRequest_=window.setTimeout(function(){return r(!1)},0)},t.dispose=function(){this.trigger("dispose"),this.stopRequest(),this.loadedPlaylists_={},window.clearTimeout(this.minimumUpdatePeriodTimeout_),window.clearTimeout(this.mediaRequest_),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.mediaRequest_=null,this.minimumUpdatePeriodTimeout_=null,this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.off()},t.hasPendingRequest=function(){return this.request||this.mediaRequest_},t.stopRequest=function(){var e;this.request&&(e=this.request,this.request=null,e.onreadystatechange=null,e.abort())},t.media=function(t){var i=this;if(!t)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var n=this.state;if("string"==typeof t){if(!this.masterPlaylistLoader_.master.playlists[t])throw new Error("Unknown playlist URI: "+t);t=this.masterPlaylistLoader_.master.playlists[t]}var e=!this.media_||t.id!==this.media_.id;if(e&&this.loadedPlaylists_[t.id]&&this.loadedPlaylists_[t.id].endList)return this.state="HAVE_METADATA",this.media_=t,void(e&&(this.trigger("mediachanging"),this.trigger("mediachange")));e&&(this.media_&&this.trigger("mediachanging"),this.addSidxSegments_(t,n,function(e){i.haveMetadata({startingState:n,playlist:t})}))},t.haveMetadata=function(e){var t=e.startingState,e=e.playlist;this.state="HAVE_METADATA",this.loadedPlaylists_[e.id]=e,this.mediaRequest_=null,this.refreshMedia_(e.id),"HAVE_MASTER"===t?this.trigger("loadedmetadata"):this.trigger("mediachange")},t.pause=function(){this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.stopRequest(),window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.isMaster_&&(window.clearTimeout(this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_),this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_=null),"HAVE_NOTHING"===this.state&&(this.started=!1)},t.load=function(e){var t=this;window.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null;var i=this.media();e?(e=i?i.targetDuration/2*1e3:5e3,this.mediaUpdateTimeout=window.setTimeout(function(){return t.load()},e)):this.started?i&&!i.endList?(this.isMaster_&&!this.minimumUpdatePeriodTimeout_&&(this.trigger("minimumUpdatePeriod"),this.updateMinimumUpdatePeriodTimeout_()),this.trigger("mediaupdatetimeout")):this.trigger("loadedplaylist"):this.start()},t.start=function(){var i=this;this.started=!0,this.isMaster_?this.requestMaster_(function(e,t){i.haveMaster_(),i.hasPendingRequest()||i.media_||i.media(i.masterPlaylistLoader_.master.playlists[0])}):this.mediaRequest_=window.setTimeout(function(){return i.haveMaster_()},0)},t.requestMaster_=function(n){var r=this;this.request=this.vhs_.xhr({uri:this.masterPlaylistLoader_.srcUrl,withCredentials:this.withCredentials},function(e,t){if(!r.requestErrored_(e,t)){var i=t.responseText!==r.masterPlaylistLoader_.masterXml_;return r.masterPlaylistLoader_.masterXml_=t.responseText,t.responseHeaders&&t.responseHeaders.date?r.masterLoaded_=Date.parse(t.responseHeaders.date):r.masterLoaded_=Date.now(),r.masterPlaylistLoader_.srcUrl=Do(r.handleManifestRedirects,r.masterPlaylistLoader_.srcUrl,t),i?(r.handleMaster_(),void r.syncClientServerClock_(function(){return n(t,i)})):n(t,i)}"HAVE_NOTHING"===r.state&&(r.started=!1)})},t.syncClientServerClock_=function(i){var n=this,r=Gs(this.masterPlaylistLoader_.masterXml_);return null===r?(this.masterPlaylistLoader_.clientOffset_=this.masterLoaded_-Date.now(),i()):"DIRECT"===r.method?(this.masterPlaylistLoader_.clientOffset_=r.value-Date.now(),i()):void(this.request=this.vhs_.xhr({uri:dl(this.masterPlaylistLoader_.srcUrl,r.value),method:r.method,withCredentials:this.withCredentials},function(e,t){if(n.request){if(e)return n.masterPlaylistLoader_.clientOffset_=n.masterLoaded_-Date.now(),i();t="HEAD"===r.method?t.responseHeaders&&t.responseHeaders.date?Date.parse(t.responseHeaders.date):n.masterLoaded_:Date.parse(t.responseText);n.masterPlaylistLoader_.clientOffset_=t-Date.now(),i()}}))},t.haveMaster_=function(){this.state="HAVE_MASTER",this.isMaster_?this.trigger("loadedplaylist"):this.media_||this.media(this.childPlaylist_)},t.handleMaster_=function(){this.mediaRequest_=null;var e,t,i,n,r=this.masterPlaylistLoader_.master,t=(a={masterXml:this.masterPlaylistLoader_.masterXml_,srcUrl:this.masterPlaylistLoader_.srcUrl,clientOffset:this.masterPlaylistLoader_.clientOffset_,sidxMapping:this.masterPlaylistLoader_.sidxMapping_,previousManifest:r},e=a.masterXml,t=a.srcUrl,i=a.clientOffset,n=a.sidxMapping,a=a.previousManifest,a=Ws(e,{manifestUri:t,clientOffset:i,sidxMapping:n,previousManifest:a}),ou(a,t),a);r&&(t=function(e,t,i){for(var a=!0,s=bl(e,{duration:t.duration,minimumUpdatePeriod:t.minimumUpdatePeriod,timelineStarts:t.timelineStarts}),n=0;n<t.playlists.length;n++){var r,o=t.playlists[n];
4716o.sidx&&(r=bs(o.sidx),i&&i[r]&&i[r].sidx&&ms(o,i[r].sidx,o.sidx.resolvedUri));o=hu(s,o,Iu);o&&(s=o,a=!1)}return au(t,function(e,t,i,n){var r;e.playlists&&e.playlists.length&&(r=e.playlists[0].id,(e=hu(s,e.playlists[0],Iu))&&((s=e).mediaGroups[t][i][n].playlists[0]=s.playlists[r],a=!1))}),(a=t.minimumUpdatePeriod===e.minimumUpdatePeriod&&a)?null:s}(r,t,this.masterPlaylistLoader_.sidxMapping_)),this.masterPlaylistLoader_.master=t||r;var a=this.masterPlaylistLoader_.master.locations&&this.masterPlaylistLoader_.master.locations[0];return a&&a!==this.masterPlaylistLoader_.srcUrl&&(this.masterPlaylistLoader_.srcUrl=a),(!r||t&&t.minimumUpdatePeriod!==r.minimumUpdatePeriod)&&this.updateMinimumUpdatePeriodTimeout_(),Boolean(t)},t.updateMinimumUpdatePeriodTimeout_=function(){var e=this.masterPlaylistLoader_;e.createMupOnMedia_&&(e.off("loadedmetadata",e.createMupOnMedia_),e.createMupOnMedia_=null),e.minimumUpdatePeriodTimeout_&&(window.clearTimeout(e.minimumUpdatePeriodTimeout_),e.minimumUpdatePeriodTimeout_=null);var t=e.master&&e.master.minimumUpdatePeriod;0===t&&(e.media()?t=1e3*e.media().targetDuration:(e.createMupOnMedia_=e.updateMinimumUpdatePeriodTimeout_,e.one("loadedmetadata",e.createMupOnMedia_))),"number"!=typeof t||t<=0?t<0&&this.logger_("found invalid minimumUpdatePeriod of "+t+", not setting a timeout"):this.createMUPTimeout_(t)},t.createMUPTimeout_=function(e){var t=this.masterPlaylistLoader_;t.minimumUpdatePeriodTimeout_=window.setTimeout(function(){t.minimumUpdatePeriodTimeout_=null,t.trigger("minimumUpdatePeriod"),t.createMUPTimeout_(e)},e)},t.refreshXml_=function(){var i=this;this.requestMaster_(function(e,t){var r,a;t&&(i.media_&&(i.media_=i.masterPlaylistLoader_.master.playlists[i.media_.id]),i.masterPlaylistLoader_.sidxMapping_=(t=i.masterPlaylistLoader_.master,r=i.masterPlaylistLoader_.sidxMapping_,a=xu(t.playlists,r),au(t,function(e,t,i,n){e.playlists&&e.playlists.length&&(e=e.playlists,a=bl(a,xu(e,r)))}),a),i.addSidxSegments_(i.media(),i.state,function(e){i.refreshMedia_(i.media().id)}))})},t.refreshMedia_=function(e){var t=this;if(!e)throw new Error("refreshMedia_ must take a media id");this.media_&&this.isMaster_&&this.handleMaster_();var i=this.masterPlaylistLoader_.master.playlists,n=!this.media_||this.media_!==i[e];n?this.media_=i[e]:this.trigger("playlistunchanged"),this.mediaUpdateTimeout||function e(){t.media().endList||(t.mediaUpdateTimeout=window.setTimeout(function(){t.trigger("mediaupdatetimeout"),e()},pu(t.media(),Boolean(n))))}(),this.trigger("loadedplaylist")},e}(ar),Sl={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,BACK_BUFFER_LENGTH:30,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:16,BUFFER_LOW_WATER_LINE_RATE:1,BUFFER_HIGH_WATER_LINE:30},x=function(n){return function(){var e=function(t){try{return URL.createObjectURL(new Blob([t],{type:"application/javascript"}))}catch(e){var i=new BlobBuilder;return i.append(t),URL.createObjectURL(i.getBlob())}}(n),t=Au(new Worker(e));t.objURL=e;var i=t.terminate;return t.on=t.addEventListener,t.off=t.removeEventListener,t.terminate=function(){return URL.revokeObjectURL(e),i.call(this)},t}},U=function(e){return"var browserWorkerPolyFill = "+Au.toString()+";\nbrowserWorkerPolyFill(self);\n"+e},W=function(e){return e.toString().replace(/^function.+?{/,"").slice(0,-1)},wl=x(U(W(function(){var e=function(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){return!!a[e]&&(t=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(t,1),-1<t)},this.trigger=function(e){var t,i,n,r=a[e];if(r)if(2===arguments.length)for(i=r.length,t=0;t<i;++t)r[t].call(this,arguments[1]);else{for(n=[],t=arguments.length,t=1;t<arguments.length;++t)n.push(arguments[t]);for(i=r.length,t=0;t<i;++t)r[t].apply(this,n)}},this.dispose=function(){a={}}}};e.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),this.on("partialdone",function(e){t.partialFlush(e)}),this.on("endedtimeline",function(e){t.endTimeline(e)}),this.on("reset",function(e){t.reset(e)}),t},e.prototype.push=function(e){this.trigger("data",e)},e.prototype.flush=function(e){this.trigger("done",e)},e.prototype.partialFlush=function(e){this.trigger("partialdone",e)},e.prototype.endTimeline=function(e){this.trigger("endedtimeline",e)},e.prototype.reset=function(e){this.trigger("reset",e)};var u,t,i,n,r,a,s,o,l,c,d,h,p,f,m,g,y,v,_,b,T,S,w,E,k,C,I,x,A,P,L,D,O,R,M,N,U,B,F,j=e,H=Math.pow(2,32),q={getUint64:function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);return t.getBigUint64?(e=t.getBigUint64(0))<Number.MAX_SAFE_INTEGER?
vendor: 7,949 bytes, line 4716
4716Number(e):e:t.getUint32(0)*H+t.getUint32(4)},MAX_UINT32:H},V=q.MAX_UINT32;!function(){if(T={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],pasp:[],sdtp:[],smhd:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],styp:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[]},"undefined"!=typeof Uint8Array){for(var e in T)T.hasOwnProperty(e)&&(T[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);S=new Uint8Array(["i".charCodeAt(0),"s".charCodeAt(0),"o".charCodeAt(0),"m".charCodeAt(0)]),E=new Uint8Array(["a".charCodeAt(0),"v".charCodeAt(0),"c".charCodeAt(0),"1".charCodeAt(0)]),w=new Uint8Array([0,0,0,1]),k=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),C=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]),I={video:k,audio:C},P=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),A=new Uint8Array([0,0,0,0,0,0,0,0]),L=new Uint8Array([0,0,0,0,0,0,0,0]),D=L,O=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),R=L,x=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}}(),u=function(e){for(var t,i=[],n=0,r=1;r<arguments.length;r++)i.push(arguments[r]);for(r=i.length;r--;)n+=i[r].byteLength;for(t=new Uint8Array(n+8),new DataView(t.buffer,t.byteOffset,t.byteLength).setUint32(0,t.byteLength),t.set(e,4),r=0,n=8;r<i.length;r++)t.set(i[r],n),n+=i[r].byteLength;return t},t=function(){return u(T.dinf,u(T.dref,P))},i=function(e){return u(T.esds,new Uint8Array([0,0,0,0,3,25,0,0,0,4,17,64,21,0,6,0,0,0,218,192,0,0,218,192,5,2,e.audioobjecttype<<3|e.samplingfrequencyindex>>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},f=function(e){return u(T.hdlr,I[e])},p=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(t[12]=e.samplerate>>>24&255,t[13]=e.samplerate>>>16&255,t[14]=e.samplerate>>>8&255,t[15]=255&e.samplerate),u(T.mdhd,t)},h=function(e){return u(T.mdia,p(e),f(e.type),a(e))},r=function(e){return u(T.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},a=function(e){return u(T.minf,"video"===e.type?u(T.vmhd,x):u(T.smhd,A),t(),g(e))},We=function(e,t){for(var i=[],n=t.length;n--;)i[n]=v(t[n]);return u.apply(null,[T.moof,r(e)].concat(i))},s=function(e){for(var t=e.length,i=[];t--;)i[t]=c(e[t]);return u.apply(null,[T.moov,l(4294967295)].concat(i).concat(o(e)))},o=function(e){for(var t=e.length,i=[];t--;)i[t]=_(e[t]);return u.apply(null,[T.mvex].concat(i))},l=function(e){e=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return u(T.mvhd,e)},m=function(e){for(var t,i=e.samples||[],n=new Uint8Array(4+i.length),r=0;r<i.length;r++)t=i[r].flags,n[r+4]=t.dependsOn<<4|t.isDependedOn<<2|t.hasRedundancy;return u(T.sdtp,n)},g=function(e){return u(T.stbl,y(e),u(T.stts,R),u(T.stsc,D),u(T.stsz,O),u(T.stco,L))},y=function(e){return u(T.stsd,new Uint8Array([0,0,0,0,0,0,0,1]),("video"===e.type?M:N)(e))},M=function(e){for(var t,i,n=e.sps||[],r=e.pps||[],a=[],s=[],o=0;o<n.length;o++)a.push((65280&n[o].byteLength)>>>8),a.push(255&n[o].byteLength),a=a.concat(Array.prototype.slice.call(n[o]));for(o=0;o<r.length;o++)s.push((65280&r[o].byteLength)>>>8),s.push(255&r[o].byteLength),s=s.concat(Array.prototype.slice.call(r[o]));return t=[T.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),u(T.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([n.length],a,[r.length],s))),u(T.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],e.sarRatio&&(i=e.sarRatio[0],e=e.sarRatio[1],t.push(u(T.pasp,new Uint8Array([(4278190080&i)>>24,(16711680&i)>>16,(65280&i)>>8,255&i,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e])))),u.apply(null,t)},N=function(e){return u(T.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),i(e))},d=function(e){e=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return u(T.tkhd,e)},v=function(e){var t,i=u(T.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),n=Math.floor(e.baseMediaDecodeTime/V),r=Math.floor(e.baseMediaDecodeTime%V),n=u(T.tfdt,new Uint8Array([1,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,r>>>24&255,r>>>16&255,r>>>8&255,255&r]));return"audio"===e.type?(t=b(e,92),u(T.traf,i,n,t)):(r=m(e),t=b(e,r.length+92),u(T.traf,i,n,t,r))},c=function(e){return e.duration=e.duration||4294967295,u(T.trak,d(e),h(e))},_=function(e){var t=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==e.type&&(t[t.length-1]=0),u(T.trex,t)},U=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},B=function(e,t){var i,n,r,a,s=e.samples||[];for(t+=20+16*s.length,t=U(s,t),(n=new Uint8Array(t.length+16*s.length)).set(t),i=t.length,a=0;a<s.length;a++)r=s[a],n[i++]=(4278190080&r.duration)>>>24,n[i++]=(16711680&r.duration)>>>16,n[i++]=(65280&r.duration)>>>8,n[i++]=255&r.duration,n[i++]=(4278190080&r.size)>>>24,n[i++]=(16711680&r.size)>>>16,n[i++]=(65280&r.size)>>>8,n[i++]=255&r.size,n[i++]=r.flags.isLeading<<2|r.flags.dependsOn,n[i++]=r.flags.isDependedOn<<6|r.flags.hasRedundancy<<4|r.flags.paddingValue<<1|r.flags.isNonSyncSample,n[i++]=61440&r.flags.degradationPriority,n[i++]=15&r.flags.degradationPriority,n[i++]=(4278190080&r.compositionTimeOffset)>>>24,n[i++]=(16711680&r.compositionTimeOffset)>>>16,n[i++]=(65280&r.compositionTimeOffset)>>>8,n[i++]=255&r.compositionTimeOffset;return u(T.trun,n)},F=function(e,t){var i,n,r,a,s=e.samples||[];for(t+=20+8*s.length,t=U(s,t),(i=new Uint8Array(t.length+8*s.length)).set(t),n=t.length,a=0;a<s.length;a++)r=s[a],i[n++]=(4278190080&r.duration)>>>24,i[n++]=(16711680&r.duration)>>>16,i[n++]=(65280&r.duration)>>>8,i[n++]=255&r.duration,i[n++]=(4278190080&r.size)>>>24,i[n++]=(16711680&r.size)>>>16,i[n++]=(65280&r.size)>>>8,i[n++]=255&r.size;return u(T.trun,i)},b=function(e,t){return("audio"===e.type?F:B)(e,t)};n=function(){return u(T.ftyp,S,w,S,E)};function W(e,t){var i={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return i.dataOffset=t,i.compositionTimeOffset=e.pts-e.dts,i.duration=e.duration,i.size=4*e.length,i.size+=e.byteLength,e.keyFrame&&(i.flags.dependsOn=2,i.flags.isNonSyncSample=0),i}function G(e){for(var t=[];e--;)t.push(0);return t}function z(){var e,i;return X||(e={96e3:[ie,[227,64],G(154),[56]],88200:[ie,[231],G(170),[56]],64e3:[ie,[248,192],G(240),[56]],48e3:[ie,[255,192],G(268),[55,148,128],G(54),[112]],44100:[ie,[25
vendor: 6,584 bytes, line 4716
47165,192],G(268),[55,163,128],G(84),[112]],32e3:[ie,[255,192],G(268),[55,234],G(226),[112]],24e3:[ie,[255,192],G(268),[55,255,128],G(268),[111,112],G(126),[224]],16e3:[ie,[255,192],G(268),[55,255,128],G(268),[111,255],G(269),[223,108],G(195),[1,192]],12e3:[ne,G(268),[3,127,248],G(268),[6,255,240],G(268),[13,255,224],G(268),[27,253,128],G(259),[56]],11025:[ne,G(268),[3,127,248],G(268),[6,255,240],G(268),[13,255,224],G(268),[27,255,192],G(268),[55,175,128],G(108),[112]],8e3:[ne,G(268),[3,121,16],G(47),[7]]},i=e,X=Object.keys(i).reduce(function(e,t){return e[t]=new Uint8Array(i[t].reduce(function(e,t){return e.concat(t)},[])),e},{})),X}var X,K=function(e){return u(T.mdat,e)},Y=We,Q=function(e){var t=n(),i=s(e),e=new Uint8Array(t.byteLength+i.byteLength);return e.set(t),e.set(i,t.byteLength),e},$=function(e){var t,i,n=[],r=[];for(r.byteLength=0,r.nalCount=0,r.duration=0,t=n.byteLength=0;t<e.length;t++)"access_unit_delimiter_rbsp"===(i=e[t]).nalUnitType?(n.length&&(n.duration=i.dts-n.dts,r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n)),(n=[i]).byteLength=i.data.byteLength,n.pts=i.pts,n.dts=i.dts):("slice_layer_without_partitioning_rbsp_idr"===i.nalUnitType&&(n.keyFrame=!0),n.duration=i.dts-n.dts,n.byteLength+=i.data.byteLength,n.push(i));return r.length&&(!n.duration||n.duration<=0)&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n),r},J=function(e){var t,i,n=[],r=[];for(n.byteLength=0,n.nalCount=0,n.duration=0,n.pts=e[0].pts,n.dts=e[0].dts,r.byteLength=0,r.nalCount=0,r.duration=0,r.pts=e[0].pts,r.dts=e[0].dts,t=0;t<e.length;t++)(i=e[t]).keyFrame?(n.length&&(r.push(n),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration),(n=[i]).nalCount=i.length,n.byteLength=i.byteLength,n.pts=i.pts,n.dts=i.dts,n.duration=i.duration):(n.duration+=i.duration,n.nalCount+=i.length,n.byteLength+=i.byteLength,n.push(i));return r.length&&n.duration<=0&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration,r.push(n),r},Z=function(e){var t;return!e[0][0].keyFrame&&1<e.length&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e},ee=function(e,t){for(var i,n,r,a=t||0,s=[],o=0;o<e.length;o++)for(n=e[o],i=0;i<n.length;i++)r=n[i],a+=(r=W(r,a)).size,s.push(r);return s},te=function(e){for(var t,i,n,r,a,s=0,o=e.byteLength,u=e.nalCount,l=new Uint8Array(o+4*u),c=new DataView(l.buffer),d=0;d<e.length;d++)for(n=e[d],t=0;t<n.length;t++)for(r=n[t],i=0;i<r.length;i++)a=r[i],c.setUint32(s,a.data.byteLength),l.set(a.data,s+=4),s+=a.data.byteLength;return l},ie=[33,16,5,32,164,27],ne=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],re=function(e){return 9e4*e},ae=function(e,t){return e*t},se=function(e){return e/9e4},oe=function(e,t){return e/t},ue=9e4,le=re,ce=se,de=function(e,t){return re(oe(e,t))},he=function(e,t){return ae(se(e),t)},pe=function(e,t,i){return se(i?e:e-t)},fe=function(e,t,i,n){var r,a,s,o,u,l,c=0,d=0;if(t.length&&(r=de(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(ue/(e.samplerate/1024)),i&&n&&(s=r-Math.max(i,n),d=(c=Math.floor(s/a))*a),!(c<1||ue/2<d))){for(o=(o=z()[e.samplerate])||t[0].data,u=0;u<c;u++)l=t[0],t.splice(0,0,{data:o,dts:l.dts-a,pts:l.pts-a});return e.baseMediaDecodeTime-=Math.floor(he(d,e.samplerate)),d}},me=function(e,t,i){return t.minSegmentDts>=i?e:(t.minSegmentDts=1/0,e.filter(function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)}))},ge=function(e){for(var t,i=[],n=0;n<e.length;n++)t=e[n],i.push({size:t.data.byteLength,duration:1024});return i},ye=function(e){for(var t,i=0,n=new Uint8Array(function(e){for(var t=0,i=0;i<e.length;i++)t+=e[i].data.byteLength;return t}(e)),r=0;r<e.length;r++)t=e[r],n.set(t.data,i),i+=t.data.byteLength;return n},ve=ue,_e=function(e){delete e.minSegmentDts,delete e.maxSegmentDts,delete e.minSegmentPts,delete e.maxSegmentPts},be=function(e,t){var i=e.minSegmentDts;return t||(i-=e.timelineStartInfo.dts),t=e.timelineStartInfo.baseMediaDecodeTime,t+=i,t=Math.max(0,t),"audio"===e.type&&(t*=e.samplerate/ve,t=Math.floor(t)),t},Te=function(e,t){"number"==typeof t.pts&&(void 0===e.timelineStartInfo.pts&&(e.timelineStartInfo.pts=t.pts),void 0===e.minSegmentPts?e.minSegmentPts=t.pts:e.minSegmentPts=Math.min(e.minSegmentPts,t.pts),void 0===e.maxSegmentPts?e.maxSegmentPts=t.pts:e.maxSegmentPts=Math.max(e.maxSegmentPts,t.pts)),"number"==typeof t.dts&&(void 0===e.timelineStartInfo.dts&&(e.timelineStartInfo.dts=t.dts),void 0===e.minSegmentDts?e.minSegmentDts=t.dts:e.minSegmentDts=Math.min(e.minSegmentDts,t.dts),void 0===e.maxSegmentDts?e.maxSegmentDts=t.dts:e.maxSegmentDts=Math.max(e.maxSegmentDts,t.dts))},Se=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){if("GA94"===String.fromCharCode(e[t+3],e[t+4],e[t+5],e[t+6])){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}i.payload=void 0}t+=r,r=n=0}return i},we=function(e){return 181!==e.payload[0]||49!=(e.payload[1]<<8|e.payload[2])||"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])||3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},Ee=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},ke=function(e){for(var t=e.byteLength,i=[],n=1;n<t-2;)0===e[n]&&0===e[n+1]&&3===e[n+2]?(i.push(n+2),n+=2):n++;if(0===i.length)return e;for(var r=t-i.length,a=new Uint8Array(r),s=0,n=0;n<r;s++,n++)s===i[0]&&(s++,i.shift()),a[n]=e[s];return a},Ce=4,Ie=function e(t){t=t||{},e.prototype.init.call(this),this.parse708captions_="boolean"!=typeof t.parse708captions||t.parse708captions,this.captionPackets_=[],this.ccStreams_=[new Ue(0,0),new Ue(0,1),new Ue(1,0),new Ue(1,1)],this.parse708captions_&&(this.cc708Stream_=new De({captionServices:t.captionServices})),this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("partialdone",this.trigger.bind(this,"partialdone")),e.on("done",this.trigger.bind(this,"done"))},this),this.parse708captions_&&(this.cc708Stream_.on("data",this.trigger.bind(this,"data")),this.cc708Stream_.on("partialdone",this.trigger.bind(this,"partialdone")),this.cc708Stream_.on("done",this.trigger.bind(this,"done")))};(Ie.prototype=new j).push=function(e){var t,i;
4716if("sei_rbsp"===e.nalUnitType&&(t=Se(e.escapedRBSP)).payload&&t.payloadType===Ce&&(i=we(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));i=Ee(e.pts,i),this.captionPackets_=this.captionPackets_.concat(i),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},Ie.prototype.flushCCStreams=function(t){this.ccStreams_.forEach(function(e){return"flush"===t?e.flush():e.partialFlush()},this)},Ie.prototype.flushStream=function(e){this.captionPackets_.length&&(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2?this.dispatchCea608Packet(e):this.dispatchCea708Packet(e)},this),this.captionPackets_.length=0),this.flushCCStreams(e)},Ie.prototype.flush=function(){return this.flushStream("flush")},Ie.prototype.partialFlush=function(){return this.flushStream("partialFlush")},Ie.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},Ie.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},Ie.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},Ie.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},Ie.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)},Ie.prototype.dispatchCea708Packet=function(e){this.parse708captions_&&this.cc708Stream_.push(e)};function xe(e){return 32<=e&&e<=127||160<=e&&e<=255}function Ae(e){this.windowNum=e,this.reset()}var Pe={127:9834,4128:32,4129:160,4133:8230,4138:352,4140:338,4144:9608,4145:8216,4146:8217,4147:8220,4148:8221,4149:8226,4153:8482,4154:353,4156:339,4157:8480,4159:376,4214:8539,4215:8540,4216:8541,4217:8542,4218:9168,4219:9124,4220:9123,4221:9135,4222:9126,4223:9121,4256:12600};Ae.prototype.reset=function(){this.clearText(),this.pendingNewLine=!1,this.winAttr={},this.penAttr={},this.penLoc={},this.penColor={},this.visible=0,this.rowLock=0,this.columnLock=0,this.priority=0,this.relativePositioning=0,this.anchorVertical=0,this.anchorHorizontal=0,this.anchorPoint=0,this.rowCount=1,this.virtualRowCount=this.rowCount+1,this.columnCount=41,this.windowStyle=0,this.penStyle=0},Ae.prototype.getText=function(){return this.rows.join("\n")},Ae.prototype.clearText=function(){this.rows=[""],this.rowIdx=0},Ae.prototype.newLine=function(e){for(this.rows.length>=this.virtualRowCount&&"function"==typeof this.beforeRowOverflow&&this.beforeRowOverflow(e),0<this.rows.length&&(this.rows.push(""),this.rowIdx++);this.rows.length>this.virtualRowCount;)this.rows.shift(),this.rowIdx--},Ae.prototype.isEmpty=function(){return 0===this.rows.length||1===this.rows.length&&""===this.rows[0]},Ae.prototype.addText=function(e){this.rows[this.rowIdx]+=e},Ae.prototype.backspace=function(){var e;this.isEmpty()||(e=this.rows[this.rowIdx],this.rows[this.rowIdx]=e.substr(0,e.length-1))};function Le(e,t,i){this.serviceNum=e,this.text="",this.currentWindow=new Ae(-1),this.windows=[],this.stream=i,"string"==typeof t&&this.createTextDecoder(t)}Le.prototype.init=function(e,t){this.startPts=e;for(var i=0;i<8;i++)this.windows[i]=new Ae(i),"function"==typeof t&&(this.windows[i].beforeRowOverflow=t)},Le.prototype.setCurrentWindow=function(e){this.currentWindow=this.windows[e]},Le.prototype.createTextDecoder=function(t){if("undefined"==typeof TextDecoder)this.stream.trigger("log",{level:"warn",message:"The `encoding` option is unsupported without TextDecoder support"});else try{this.textDecoder_=new TextDecoder(t)}catch(e){this.stream.trigger("log",{level:"warn",message:"TextDecoder could not be created with "+t+" encoding. "+e})}};var De=function e(t){t=t||{},e.prototype.init.call(this);var i,n=this,r=t.captionServices||{},a={};Object.keys(r).forEach(function(e){i=r[e],/^SERVICE/.test(e)&&(a[e]=i.encoding)}),this.serviceEncodings=a,this.current708Packet=null,this.services={},this.push=function(e){(3===e.type||null===n.current708Packet)&&n.new708Packet(),n.add708Bytes(e)}};De.prototype=new j,De.prototype.new708Packet=function(){null!==this.current708Packet&&this.push708Packet(),this.current708Packet={data:[],ptsVals:[]}},De.prototype.add708Bytes=function(e){var t=e.ccData,i=t>>>
vendor: 9,399 bytes, line 4716
47168,t=255&t;this.current708Packet.ptsVals.push(e.pts),this.current708Packet.data.push(i),this.current708Packet.data.push(t)},De.prototype.push708Packet=function(){var e,t=this.current708Packet,i=t.data,n=null,r=0,a=i[r++];for(t.seq=a>>6,t.sizeCode=63&a;r<i.length;r++)e=31&(a=i[r++]),7===(n=a>>5)&&0<e&&(n=i[r++]),this.pushServiceBlock(n,r,e),0<e&&(r+=e-1)},De.prototype.pushServiceBlock=function(e,t,i){for(var n,r=t,a=this.current708Packet.data,s=(s=this.services[e])||this.initService(e,r);r<t+i&&r<a.length;r++)n=a[r],xe(n)?r=this.handleText(r,s):24===n?r=this.multiByteCharacter(r,s):16===n?r=this.extendedCommands(r,s):128<=n&&n<=135?r=this.setCurrentWindow(r,s):152<=n&&n<=159?r=this.defineWindow(r,s):136===n?r=this.clearWindows(r,s):140===n?r=this.deleteWindows(r,s):137===n?r=this.displayWindows(r,s):138===n?r=this.hideWindows(r,s):139===n?r=this.toggleWindows(r,s):151===n?r=this.setWindowAttributes(r,s):144===n?r=this.setPenAttributes(r,s):145===n?r=this.setPenColor(r,s):146===n?r=this.setPenLocation(r,s):143===n?s=this.reset(r,s):8===n?s.currentWindow.backspace():12===n?s.currentWindow.clearText():13===n?s.currentWindow.pendingNewLine=!0:14===n?s.currentWindow.clearText():141===n&&r++},De.prototype.extendedCommands=function(e,t){var i=this.current708Packet.data[++e];return e=xe(i)?this.handleText(e,t,{isExtended:!0}):e},De.prototype.getPts=function(e){return this.current708Packet.ptsVals[Math.floor(e/2)]},De.prototype.initService=function(t,e){var i,n="SERVICE"+t,r=this;return n in this.serviceEncodings&&(i=this.serviceEncodings[n]),this.services[t]=new Le(t,i,r),this.services[t].init(this.getPts(e),function(e){r.flushDisplayed(e,r.services[t])}),this.services[t]},De.prototype.handleText=function(e,t,i){var n,r=i&&i.isExtended,a=i&&i.isMultiByte,s=this.current708Packet.data,o=r?4096:0,u=s[e],i=s[e+1],s=t.currentWindow,l=t.textDecoder_&&!r?(a?(n=[u,i],e++):n=[u],t.textDecoder_.decode(new Uint8Array(n))):(l=Pe[u=o|u]||u,4096&u&&u===l?"":String.fromCharCode(l));return s.pendingNewLine&&!s.isEmpty()&&s.newLine(this.getPts(e)),s.pendingNewLine=!1,s.addText(l),e},De.prototype.multiByteCharacter=function(e,t){var i=this.current708Packet.data,n=i[e+1],i=i[e+2];return e=xe(n)&&xe(i)?this.handleText(++e,t,{isMultiByte:!0}):e},De.prototype.setCurrentWindow=function(e,t){var i=this.current708Packet.data[e];return t.setCurrentWindow(7&i),e},De.prototype.defineWindow=function(e,t){var i=this.current708Packet.data,n=i[e];t.setCurrentWindow(7&n);t=t.currentWindow,n=i[++e];return t.visible=(32&n)>>5,t.rowLock=(16&n)>>4,t.columnLock=(8&n)>>3,t.priority=7&n,n=i[++e],t.relativePositioning=(128&n)>>7,t.anchorVertical=127&n,n=i[++e],t.anchorHorizontal=n,n=i[++e],t.anchorPoint=(240&n)>>4,t.rowCount=15&n,n=i[++e],t.columnCount=63&n,n=i[++e],t.windowStyle=(56&n)>>3,t.penStyle=7&n,t.virtualRowCount=t.rowCount+1,e},De.prototype.setWindowAttributes=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.winAttr,n=i[++e];return t.fillOpacity=(192&n)>>6,t.fillRed=(48&n)>>4,t.fillGreen=(12&n)>>2,t.fillBlue=3&n,n=i[++e],t.borderType=(192&n)>>6,t.borderRed=(48&n)>>4,t.borderGreen=(12&n)>>2,t.borderBlue=3&n,n=i[++e],t.borderType+=(128&n)>>5,t.wordWrap=(64&n)>>6,t.printDirection=(48&n)>>4,t.scrollDirection=(12&n)>>2,t.justify=3&n,n=i[++e],t.effectSpeed=(240&n)>>4,t.effectDirection=(12&n)>>2,t.displayEffect=3&n,e},De.prototype.flushDisplayed=function(e,t){for(var i=[],n=0;n<8;n++)t.windows[n].visible&&!t.windows[n].isEmpty()&&i.push(t.windows[n].getText());t.endPts=e,t.text=i.join("\n\n"),this.pushCaption(t),t.startPts=e},De.prototype.pushCaption=function(e){""!==e.text&&(this.trigger("data",{startPts:e.startPts,endPts:e.endPts,text:e.text,stream:"cc708_"+e.serviceNum}),e.text="",e.startPts=e.endPts)},De.prototype.displayWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible=1);return e},De.prototype.hideWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible=0);return e},De.prototype.toggleWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible^=1);return e},De.prototype.clearWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&t.windows[r].clearText();return e},De.prototype.deleteWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&t.windows[r].reset();return e},De.prototype.setPenAttributes=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.penAttr,n=i[++e];return t.textTag=(240&n)>>4,t.offset=(12&n)>>2,t.penSize=3&n,n=i[++e],t.italics=(128&n)>>7,t.underline=(64&n)>>6,t.edgeType=(56&n)>>3,t.fontStyle=7&n,e},De.prototype.setPenColor=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.penColor,n=i[++e];return t.fgOpacity=(192&n)>>6,t.fgRed=(48&n)>>4,t.fgGreen=(12&n)>>2,t.fgBlue=3&n,n=i[++e],t.bgOpacity=(192&n)>>6,t.bgRed=(48&n)>>4,t.bgGreen=(12&n)>>2,t.bgBlue=3&n,n=i[++e],t.edgeRed=(48&n)>>4,t.edgeGreen=(12&n)>>2,t.edgeBlue=3&n,e},De.prototype.setPenLocation=function(e,t){var i=this.current708Packet.data,n=i[e],r=t.currentWindow.penLoc;return t.currentWindow.pendingNewLine=!0,n=i[++e],r.row=15&n,n=i[++e],r.column=63&n,e},De.prototype.reset=function(e,t){var i=this.getPts(e);return this.flushDisplayed(i,t),this.initService(t.serviceNum,e)};function Oe(e){return null===e?"":(e=Me[e]||e,String.fromCharCode(e))}function Re(){for(var e=[],t=15;t--;)e.push("");return e}var Me={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},Ne=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Ue=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a=32639&e.ccData;a!==this.lastControlCode_?(4096==(61440&a)?this.lastControlCode_=a:a!==this.PADDING_&&(this.lastControlCode_=null),t=a>>>8,i=255&a,a===this.PADDING_||(a===this.RESUME_CAPTION_LOADING_?this.mode_="popOn":a===this.END_OF_CAPTION_?(this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),r=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=r,this.startPts_=e.pts):a===this.ROLL_UP_2_ROWS_?(this.rollUpRows_=2,this.setRollUp(e.pts)):a===this.ROLL_UP_3_ROWS_?(this.rollUpRows_=3,this.setRollUp(e.pts)):a===this.ROLL_UP_4_ROWS_?(this.rollUpRows_=4,this.setRollUp(e.pts)):a===this.CARRIAGE_RETURN_?(this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts):a===this.BACKSPACE_?"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1):a===this.ERASE_DISPLAYED_MEMORY_?(this.flushDisplayed(e.pts),this.displayed_=Re()):a===this.ERASE_NON_DISPLAYED_MEMORY_?this.nonDisplayed_=Re():a===this.RESUME_DIRECT_CAPTIONING_?("paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=Re()),this.mode_="paintOn",this.startPts_=e.pts):this.isSpecialCharacter(t,i)?(n=Oe((t=(3&t)<<8)|i),this[this.mode_](e.pts,n),this.column_++):this.isExtCharacter(t,i)?("popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),n=Oe((t=(3&t)<<8)|i),this[this.mode_](e.pts,n),this.column_++):this.isMidRowCode(t,i)?(this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&i)&&this.addFormatting(e.pts,["i"]),1==(1&i)&&this.addFormatting(e.pts,["u"])):this.isOffsetControlCode(t,i)?this.column_+=3&i:this.isPAC(t,i)?(r=Ne.indexOf(7968&a),"rollUp"===this.mode_&&(r-this.rollUpRows_+1<0&&(r=this.rollUpRows_-1),this.setRollUp(e.pts,r)),r!==this.row_&&(this.clearFormatting(e.pts),this.row_=r),1&i&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&a)&&(this.column_=4*((14&a)>>1)),this.isColorPAC(i)&&14==(14&i)&&this.addFormatting(e.pts,["i"])):this.isNormalChar(t)&&(0===i&&(i=null),n=Oe(t),n+=Oe(i),this[this.mode_](e.pts,n),this.column_+=n.length))):this.lastControlCode_=null}};Ue.prototype=new j,Ue.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e,t){try{return e.trim()}catch(e){return this.trigger("log",{level:"warn",message:"Skipping a malformed 608 caption at index "+t+"."}),""}},this).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream
vendor: 5,760 bytes, line 4716
4716:this.name_})},Ue.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=Re(),this.nonDisplayed_=Re(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Ue.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},Ue.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},Ue.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},Ue.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},Ue.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},Ue.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},Ue.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},Ue.prototype.isNormalChar=function(e){return 32<=e&&e<=127},Ue.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=Re(),this.displayed_=Re()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},Ue.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);t=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,t)},Ue.prototype.clearFormatting=function(e){var t;this.formatting_.length&&(t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},""),this.formatting_=[],this[this.mode_](e,t))},Ue.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];this.nonDisplayed_[this.row_]=i+=t},Ue.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];this.displayed_[this.row_]=i+=t},Ue.prototype.shiftRowsUp_=function(){for(var e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},Ue.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];this.displayed_[this.row_]=i+=t};function Be(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}var Fe={CaptionStream:Ie,Cea608Stream:Ue,Cea708Stream:De},je={H264_STREAM_TYPE:27,ADTS_STREAM_TYPE:15,METADATA_STREAM_TYPE:21},e=function e(t){var i,n;e.prototype.init.call(this),this.type_=t||"shared",this.push=function(e){"shared"!==this.type_&&e.type!==this.type_||(void 0===n&&(n=e.dts),e.dts=Be(e.dts,n),e.pts=Be(e.pts,n),i=e.dts,this.trigger("data",e))},this.flush=function(){n=i,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.discontinuity=function(){i=n=void 0},this.reset=function(){this.discontinuity(),this.trigger("reset")}};e.prototype=new j;function He(e,t,i){for(var n="",r=t;r<i;r++)n+="%"+("00"+e[r].toString(16)).slice(-2);return n}function qe(e,t,i){return decodeURIComponent(He(e,t,i))}function Ve(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var We=e,Ie=Be,Ge={TXXX:function(e){var t;if(3===e.data[0]){for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=qe(e.data,1,t),e.value=qe(e.data,t+1,e.data.length).replace(/\0*$/,"");break}e.data=e.value}},WXXX:function(e){var t;if(3===e.data[0])for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=qe(e.data,1,t),e.url=qe(e.data,t+1,e.data.length);break}},PRIV:function(e){for(var t,i=0;i<e.data.length;i++)if(0===e.data[i]){e.owner=(t=e.data,unescape(He(t,0,i)));break}e.privateData=e.data.subarray(i+1),e.data=e.privateData}},ze=function(e){var t,i={descriptor:e&&e.descriptor},u=0,l=[],c=0;if(ze.prototype.init.call(this),this.dispatchType=je.METADATA_STREAM_TYPE.toString(16),i.descriptor)for(t=0;t<i.descriptor.length;t++)this.dispatchType+=("00"+i.descriptor[t].toString(16)).slice(-2);this.push=function(e){var t,i,n,r,a,s,o;if("timed-metadata"===e.type)if(e.dataAlignmentIndicator&&(c=0,l.length=0),0===l.length&&(e.data.length<10||e.data[0]!=="I".charCodeAt(0)||e.data[1]!=="D".charCodeAt(0)||e.data[2]!=="3".charCodeAt(0)))this.trigger("log",{level:"warn",message:"Skipping unrecognized metadata packet"});else if(l.push(e),c+=e.data.byteLength,1===l.length&&(u=Ve(e.data.subarray(6,10)),u+=10),!(c<u)){for(t={data:new Uint8Array(u),frames:[],pts:l[0].pts,dts:l[0].dts},r=0;r<u;)t.data.set(l[0].data.subarray(0,u-r),r),r+=l[0].data.byteLength,c-=l[0].data.byteLength,l.shift();i=10,64&t.data[5]&&(i+=4,i+=Ve(t.data.subarray(10,14)),u-=Ve(t.data.subarray(16,20)));do{if((n=Ve(t.data.subarray(i+4,i+8)))<1)return void this.trigger("log",{level:"warn",message:"Malformed ID3 frame encountered. Skipping metadata parsing."})}while((o={id:String.fromCharCode(t.data[i],t.data[i+1],t.data[i+2],t.data[i+3]),data:t.data.subarray(i+10,i+n+10)}).key=o.id,Ge[o.id]&&(Ge[o.id](o),"com.apple.streaming.transportStreamTimestamp"===o.owner&&(s=(1&(a=o.data)[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2,s*=4,s+=3&a[7],o.timeStamp=s,void 0===t.pts&&void 0===t.dts&&(t.pts=o.timeStamp,t.dts=o.timeStamp),this.trigger("timestamp",o))),t.frames.push(o),i+=10,(i+=n)<u);this.trigger("data",t)}}};ze.prototype=new j;
vendor: 11,044 bytes, line 4716
4716var Xe,Ke,e=ze,We=We,Ye=function(){var r=new Uint8Array(188),a=0;Ye.prototype.init.call(this),this.push=function(e){var t,i=0,n=188;for(a?((t=new Uint8Array(e.byteLength+a)).set(r.subarray(0,a)),t.set(e,a),a=0):t=e;n<t.byteLength;)71!==t[i]||71!==t[n]?(i++,n++):(this.trigger("data",t.subarray(i,n)),i+=188,n+=188);i<t.byteLength&&(r.set(t.subarray(i),0),a=t.byteLength-i)},this.flush=function(){188===a&&71===r[0]&&(this.trigger("data",r),a=0),this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.reset=function(){a=0,this.trigger("reset")}};Ye.prototype=new j,(Xe=function(){var n,r,a,s;Xe.prototype.init.call(this),(s=this).packetsWaitingForPmt=[],this.programMapTable=void 0,n=function(e,t){var i=0;t.payloadUnitStartIndicator&&(i+=e[i]+1),("pat"===t.type?r:a)(e.subarray(i),t)},r=function(e,t){t.section_number=e[7],t.last_section_number=e[8],s.pmtPid=(31&e[10])<<8|e[11],t.pmtPid=s.pmtPid},a=function(e,t){var i,n;if(1&e[5]){for(s.programMapTable={video:null,audio:null,"timed-metadata":{}},i=3+((15&e[1])<<8|e[2])-4,n=12+((15&e[10])<<8|e[11]);n<i;){var r=e[n],a=(31&e[n+1])<<8|e[n+2];r===je.H264_STREAM_TYPE&&null===s.programMapTable.video?s.programMapTable.video=a:r===je.ADTS_STREAM_TYPE&&null===s.programMapTable.audio?s.programMapTable.audio=a:r===je.METADATA_STREAM_TYPE&&(s.programMapTable["timed-metadata"][a]=r),n+=5+((15&e[n+3])<<8|e[n+4])}t.programMapTable=s.programMapTable}},this.push=function(e){var t={},i=4;if(t.payloadUnitStartIndicator=!!(64&e[1]),t.pid=31&e[1],t.pid<<=8,t.pid|=e[2],1<(48&e[3])>>>4&&(i+=e[i]+1),0===t.pid)t.type="pat",n(e.subarray(i),t),this.trigger("data",t);else if(t.pid===this.pmtPid)for(t.type="pmt",n(e.subarray(i),t),this.trigger("data",t);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([e,i,t]):this.processPes_(e,i,t)},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=je.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=je.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i)}}).prototype=new j,Xe.STREAM_TYPES={h264:27,adts:15},(Ke=function(){function n(e,t,i){var n,r,a,s,o=new Uint8Array(e.size),u={type:t},l=0,c=0;if(e.data.length&&!(e.size<9)){for(u.trackId=e.data[0].pid,l=0;l<e.data.length;l++)n=e.data[l],o.set(n.data,c),c+=n.data.byteLength;a=u,s=(r=o)[0]<<16|r[1]<<8|r[2],a.data=new Uint8Array,1==s&&(a.packetLength=6+(r[4]<<8|r[5]),a.dataAlignmentIndicator=0!=(4&r[6]),192&(s=r[7])&&(a.pts=(14&r[9])<<27|(255&r[10])<<20|(254&r[11])<<12|(255&r[12])<<5|(254&r[13])>>>3,a.pts*=4,a.pts+=(6&r[13])>>>1,a.dts=a.pts,64&s&&(a.dts=(14&r[14])<<27|(255&r[15])<<20|(254&r[16])<<12|(255&r[17])<<5|(254&r[18])>>>3,a.dts*=4,a.dts+=(6&r[18])>>>1)),a.data=r.subarray(9+r[8])),t="video"===t||u.packetLength<=e.size,(i||t)&&(e.size=0,e.data.length=0),t&&d.trigger("data",u)}}var t,d=this,r=!1,a={data:[],size:0},s={data:[],size:0},o={data:[],size:0};Ke.prototype.init.call(this),this.push=function(i){({pat:function(){},pes:function(){var e,t;switch(i.streamType){case je.H264_STREAM_TYPE:e=a,t="video";break;case je.ADTS_STREAM_TYPE:e=s,t="audio";break;case je.METADATA_STREAM_TYPE:e=o,t="timed-metadata";break;default:return}i.payloadUnitStartIndicator&&n(e,t,!0),e.data.push(i),e.size+=i.data.byteLength},pmt:function(){var e={type:"metadata",tracks:[]};null!==(t=i.programMapTable).video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),r=!0,d.trigger("data",e)}})[i.type]()},this.reset=function(){a.size=0,a.data.length=0,s.size=0,s.data.length=0,this.trigger("reset")},this.flushStreams_=function(){n(a,"video"),n(s,"audio"),n(o,"timed-metadata")},this.flush=function(){var e;!r&&t&&(e={type:"metadata",tracks:[]},null!==t.video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),d.trigger("data",e)),r=!1,this.flushStreams_(),this.trigger("done")}}).prototype=new j;var Qe,$e={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:Ye,TransportParseStream:Xe,ElementaryStream:Ke,TimestampRolloverStream:We,CaptionStream:Fe.CaptionStream,Cea608Stream:Fe.Cea608Stream,Cea708Stream:Fe.Cea708Stream,MetadataStream:e};for(Qe in je)je.hasOwnProperty(Qe)&&($e[Qe]=je[Qe]);var Je=$e,Ze=ue,et=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],tt=function(u){var l,c=0;tt.prototype.init.call(this),this.skipWarn_=function(e,t){this.trigger("log",{level:"warn",message:"adts skiping bytes "+e+" to "+t+" in frame "+c+" outside syncword"})},this.push=function(e){var t,i,n,r,a,s,o=0;if(u||(c=0),"audio"===e.type){for(l&&l.length?(n=l,(l=new Uint8Array(n.byteLength+e.data.byteLength)).set(n),l.set(e.data,n.byteLength)):l=e.data;o+7<l.length;)if(255===l[o]&&240==(246&l[o+1])){if("number"==typeof s&&(this.skipWarn_(s,o),s=null),i=2*(1&~l[o+1]),t=(3&l[o+3])<<11|l[o+4]<<3|(224&l[o+5])>>5,a=(r=1024*(1+(3&l[o+6])))*Ze/et[(60&l[o+2])>>>2],l.byteLength-o<t)break;this.trigger("data",{pts:e.pts+c*a,dts:e.dts+c*a,sampleCount:r,audioobjecttype:1+(l[o+2]>>>6&3),channelcount:(1&l[o+2])<<2|(192&l[o+3])>>>6,samplerate:et[(60&l[o+2])>>>2],samplingfrequencyindex:(60&l[o+2])>>>2,samplesize:16,data:l.subarray(o+7+i,o+t)}),c++,o+=t}else"number"!=typeof s&&(s=o),o++;"number"==typeof s&&(this.skipWarn_(s,o),s=null),l=l.subarray(o)}},this.flush=function(){c=0,this.trigger("done")},this.reset=function(){l=void 0,this.trigger("reset")},this.endTimeline=function(){l=void 0,this.trigger("endedtimeline")}};tt.prototype=new j;var it,nt,rt=tt,at=function(n){var r=n.byteLength,a=0,s=0;this.length=function(){return 8*r},this.bitsAvailable=function(){return 8*r+s},this.loadWord=function(){var e=n.byteLength-r,t=new Uint8Array(4),i=Math.min(4,r);if(0===i)throw new Error("no bytes available");t.set(n.subarray(e,e+i)),a=new DataView(t.buffer).getUint32(0),s=8*i,r-=i},this.skipBits=function(e){var t;e<s||(e-=s,e-=8*(t=Math.floor(e/8)),r-=t,this.loadWord()),a<<=e,s-=e},this.readBits=function(e){var t=Math.min(s,e),i=a>>>32-t;return 0<(s-=t)?a<<=t:0<r&&this.loadWord(),0<(t=e-t)?i<<t|this.readBits(t):i},this.skipLeadingZeros=function(){for(var e=0;e<s;++e)if(0!=(a&2147483648>>>e))return a<<=e,s-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()},st=function(){var n,r,a=0;st.prototype.init.call(this),this.push=function(e){for(var t,i=(r=r?((t=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),t.set(e.data,r.byteLength),t):e.data).byteLength;a<i-3;a++)if(1===r[a+2]){n=a+5;break}for(;n<i;)switch(r[n]){case 0:if(0!==r[n-1]){n+=2;break}if(0!==r[n-2]){n++;break}for(a+3!==n-2&&this.trigger("data",r.subarray(a+3,n-2));1!==r[++n]&&n<i;);a=n-2,n+=3;break;case 1:if(0!==r[n-1]||0!==r[n-2]){n+=3;break}this.trigger("data",r.subarray(a+3,n-2)),a=n-2,n+=3;break;default:n+=3}r=r.subarray(a),n-=a,a=0},this.reset=function(){r=null,a=0,this.trigger("reset")},this.flush=function(){r&&3<r.byteLength&&this.trigger("data",r.subarray(a+3)),r=null,a=0,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")}};st.prototype=new j,nt={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(it=function(){var i,n,r,a,s,o,m,t=new st;it.prototype.init.call(this),(i=this).push=function(e){"video"===e.type&&(n=e.trackId,r=e.pts,a=e.dts,t.push(e))},t.on("data",function(e){var t={trackId:n,pts:r,dts:a,data:e,nalUnitTypeCode:31&e[0]};switch(t.nalUnitTypeCode){case 5:t.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:t.nalUnitType="sei_rbsp",t.escapedRBSP=s(e.subarray(1));break;case 7:t.nalUnitType="seq_parameter_set_rbsp",t.escapedRBSP=s(e.subarray(1)),t.config=o(t.escapedRBSP);break;case 8:t.nalUnitType="pic_parameter_set_rbsp";break;case 9:t.nalUnitType="access_unit_delimiter_rbsp"}i.trigger("data",t)}),t.on("done",function(){i.trigger("done")}),t.on("partialdone",function(){i.trigger("partialdone")}),t.on("reset",function(){i.trigger("reset")}),t.on("endedtimeline",function(){i.trigger("endedtimeline")}),this.flush=function(){t.flush()},this.partialFlush=function(){t.partialFlush()},this.reset=function(){t.reset()},this.endTimeline=function(){t.endTimeline()},m=function(e,t){for(var i=8,n=8,r=0;r<e;r++)i=0===(n=0!==n?(i+t.readExpGolomb()+256)%256:n)?i:n},s=function(e){for(var t=e.byteLength,i=[],n=1;n<t-2;)0===e[n]&&0===e[n+1]&&3===e[n+2]?(i.push(n+2),n+=2):n++;if(0===i.length)return e;for(var r=t-i.length,a=new Uint8Array(r),s=0,n=0;n<r;s++,n++)s===i[0]&&(s++,i.shift()),a[n]=e[s];return a},o=function(e){var t,i,n,r,a,s=0,o=0,u=0,l=0,c=[1,1],d=new at(e),h=d.readUnsignedByte(),p=d.readUnsignedByte(),f=d.readUnsignedByte();if(d.skipUnsignedExpGolomb(),nt[h]&&(3===(i=d.readUnsignedExpGolomb())&&d.skipBits(1),d.skipUnsignedExpGolomb(),d.skipUnsignedExpGolomb(),d.skipBits(1),d.readBoolean()))for(r=3!==i?8:12,a=0;a<r;a++)d.readBoolean()&&m(a<6?16:64,d);if(d.skipUnsignedExpGolomb(),0===(n=d.readUnsignedExpGolomb()))d.readUnsignedExpGolomb();else if(1===n)for(d.skipBits(1),d.skipExpGolomb(),d.skipExpGolomb(),t=d.readUnsignedExpGolomb(),a=0;a<t;a++)d.skipExpGolomb();if(d.skipUnsignedExpGolomb(),d.skipBits(1),e=d.readUnsignedExpGolomb(),i=d.readUnsignedExpGolomb(),0===(n=d.readBits(1))&&d.skipBits(1),d.skipBits(1),d.readBoolean()&&(s=d.readUnsignedExpGolomb(),o=d.readUnsignedExpGolomb(),u=d.readUnsignedExpGolomb(),l=d.readUnsignedExpGolomb()),d.readBoolean()&&d.readBoolean()){switch(d.readUnsignedByte()){case 1:c=[1,1];break;case 2:c=[12,11];break;case 3:c=[10,11];break;case 4:c=[16,11];break;case 5:c=[40,33];break;case 6:c=[24,11];break;case 7:c=[20,11];break;case 8:c=[32,11];break;case 9:c=[80,33];break;case 10:c=[18,11];break;case 11:c=[15,11];break;case 12:c=[64,33];break;case 13:c=[160,99];break;case 14:c=[4,3];break;case 15:c=[3,2];break;case 16:c=[2,1];break;case 255:c=[d.readUnsignedByte()<<8|d.readUnsignedByte(),d.readUnsignedByte()<<8|d.readUnsignedByte()]}c&&(c[0],c[1])}return{profileIdc:h,levelIdc:f,profileCompatibility:p,width:16*(e+1)-2*s-2*o,height:(2-n)*(i+1)*16-2*u-2*l,sarRatio:c}}}).prototype=new j;function ot(e,t){var i=0<=(i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9])?i:0;return(16&e[t+5])>>4?i+20:i+10}function ut(e,t){return e.length-t<10||e[t]!=="I".charCodeAt(0)||e[t+1
4716]!=="D".charCodeAt(0)||e[t+2]!=="3".charCodeAt(0)?t:ut(e,t+=ot(e,t))}function lt(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var e={H264Stream:it,NalByteStream:st},ct=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],dt={isLikelyAacData:function(e){var t=ut(e,0);return e.length>=t+2&&255==(255&e[t])&&240==(240&e[t+1])&&16==(22&e[t+1])},parseId3TagSize:ot,parseAdtsSize:function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i},parseType:function(e,t){return e[t]==="I".charCodeAt(0)&&e[t+1]==="D".charCodeAt(0)&&e[t+2]==="3".charCodeAt(0)?"timed-metadata":!0&e[t]&&240==(240&e[t+1])?"audio":null},parseSampleRate:function(e){for(var t=0;t+5<e.length;){if(255===e[t]&&240==(246&e[t+1]))return ct[(60&e[t+2])>>>2];t++}return null},parseAacTimestamp:function(e){var t,i=10;64&e[5]&&(i+=4,i+=lt(e.subarray(10,14)));do{if((t=lt(e.subarray(i+4,i+8)))<1)return null;if("PRIV"===String.fromCharCode(e[i],e[i+1],e[i+2],e[i+3]))for(var n=e.subarray(i+10,i+t+10),r=0;r<n.byteLength;r++)if(0===n[r]){if("com.apple.streaming.transportStreamTimestamp"!==unescape(function(e,t,i){for(var n="",r=t;r<i;r++)n+="%"+("00"+e[r].toString(16)).slice(-2);return n}(n,0,r)))break;var a=n.subarray(r+1),s=(1&a[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2;return s*=4,s+=3&a[7]}}while(i+=10,(i+=t)<e.byteLength);return null}},ht=function(){var a=new Uint8Array,s=0;ht.prototype.init.call(this),this.setTimestamp=function(e){s=e},this.push=function(e){var t,i,n=0,r=0;for(a.length?(i=a.length,(a=new Uint8Array(e.byteLength+i)).set(a.subarray(0,i)),a.set(e,i)):a=e;3<=a.length-r;)if(a[r]!=="I".charCodeAt(0)||a[r+1]!=="D".charCodeAt(0)||a[r+2]!=="3".charCodeAt(0))if(255!=(255&a[r])||240!=(240&a[r+1]))r++;else{if(a.length-r<7)break;if(r+(n=dt.parseAdtsSize(a,r))>a.length)break;t={type:"audio",data:a.subarray(r,r+n),pts:s,dts:s},this.trigger("data",t),r+=n}else{if(a.length-r<10)break;if(r+(n=dt.parseId3TagSize(a,r))>a.length)break;t={type:"timed-metadata",data:a.subarray(r,r+n)},this.trigger("data",t),r+=n}e=a.length-r,a=0<e?a.subarray(r):new Uint8Array},this.reset=function(){a=new Uint8Array,this.trigger("reset")},this.endTimeline=function(){a=new Uint8Array,this.trigger("endedtimeline")}};ht.prototype=new j;function pt(e,t){t.stream=e,this.trigger("log",t)}function ft(e,t){for(var i=Object.keys(t),n=0;n<i.length;n++){var r=i[n];"headOfPipeline"!==r&&t[r].on&&t[r].on("log",pt.bind(e,r))}}function mt(e,t){var i;if(e.length===t.length){for(i=0;i<e.length;i++)if(e[i]!==t[i])return;return 1}}function gt(e,t,i,n,r,a){return{start:{dts:e,pts:e+(i-t)},end:{dts:e+(n-t),pts:e+(r-i)},prependedContentDuration:a,baseMediaDecodeTime:e}}var yt,vt,_t,bt=ht,Tt=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],St=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"],wt=e.H264Stream,Et=dt.isLikelyAacData,kt=ue,Ct=function(a,s){var o=[],u=0,l=0,c=1/0,d=(s=s||{}).firstSequenceNumber||0;Ct.prototype.init.call(this),this.push=function(t){Te(a,t),a&&Tt.forEach(function(e){a[e]=t[e]}),o.push(t)},this.setEarliestDts=function(e){u=e},this.setVideoBaseMediaDecodeTime=function(e){c=e},this.setAudioAppendStart=function(e){l=e},this.flush=function(){var e,t,i,n,r;0!==o.length&&(e=me(o,a,u),a.baseMediaDecodeTime=be(a,s.keepOriginalTimestamps),r=fe(a,e,l,c),a.samples=ge(e),t=K(ye(e)),o=[],n=Y(d,[a]),i=new Uint8Array(n.byteLength+t.byteLength),d++,i.set(n),i.set(t,n.byteLength),_e(a),n=Math.ceil(1024*kt/a.samplerate),e.length&&(n=e.length*n,this.trigger("segmentTimingInfo",gt(de(a.baseMediaDecodeTime,a.samplerate),e[0].dts,e[0].pts,e[0].dts+n,e[0].pts+n,r||0)),this.trigger("timingInfo",{start:e[0].pts,end:e[0].pts+n})),this.trigger("data",{track:a,boxes:i})),this.trigger("done","AudioSegmentStream")},this.reset=function(){_e(a),o=[],this.trigger("reset")}};Ct.prototype=new j,(yt=function(s,a){var t,i,o=[],l=[],u=(a=a||{}).firstSequenceNumber||0;yt.prototype.init.call(this),delete s.minPTS,this.gopCache_=[],this.push=function(e){Te(s,e),"seq_parameter_set_rbsp"!==e.nalUnitType||t||(t=e.config,s.sps=[e.data],St.forEach(function(e){s[e]=t[e]}
vendor: 5,015 bytes, line 4716
4716,this)),"pic_parameter_set_rbsp"!==e.nalUnitType||i||(i=e.data,s.pps=[e.data]),o.push(e)},this.flush=function(){for(var e,t,i,n=0;o.length&&"access_unit_delimiter_rbsp"!==o[0].nalUnitType;)o.shift();if(0===o.length)return this.resetStream_(),void this.trigger("done","VideoSegmentStream");if(e=$(o),(t=J(e))[0][0].keyFrame||((i=this.getGopForFusion_(o[0],s))?(n=i.duration,t.unshift(i),t.byteLength+=i.byteLength,t.nalCount+=i.nalCount,t.pts=i.pts,t.dts=i.dts,t.duration+=i.duration):t=Z(t)),l.length){var r=a.alignGopsAtEnd?this.alignGopsAtEnd_(t):this.alignGopsAtStart_(t);if(!r)return this.gopCache_.unshift({gop:t.pop(),pps:s.pps,sps:s.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),o=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");_e(s),t=r}Te(s,t),s.samples=ee(t),e=K(te(t)),s.baseMediaDecodeTime=be(s,a.keepOriginalTimestamps),this.trigger("processedGopsInfo",t.map(function(e){return{pts:e.pts,dts:e.dts,byteLength:e.byteLength}})),i=t[0],r=t[t.length-1],this.trigger("segmentTimingInfo",gt(s.baseMediaDecodeTime,i.dts,i.pts,r.dts+r.duration,r.pts+r.duration,n)),this.trigger("timingInfo",{start:t[0].pts,end:t[t.length-1].pts+t[t.length-1].duration}),this.gopCache_.unshift({gop:t.pop(),pps:s.pps,sps:s.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),o=[],this.trigger("baseMediaDecodeTime",s.baseMediaDecodeTime),this.trigger("timelineStartInfo",s.timelineStartInfo),n=Y(u,[s]),t=new Uint8Array(n.byteLength+e.byteLength),u++,t.set(n),t.set(e,n.byteLength),this.trigger("data",{track:s,boxes:t}),this.resetStream_(),this.trigger("done","VideoSegmentStream")},this.reset=function(){this.resetStream_(),o=[],this.gopCache_.length=0,l.length=0,this.trigger("reset")},this.resetStream_=function(){_e(s),i=t=void 0},this.getGopForFusion_=function(e){for(var t,i,n,r=1/0,a=0;a<this.gopCache_.length;a++)i=(n=this.gopCache_[a]).gop,s.pps&&mt(s.pps[0],n.pps[0])&&s.sps&&mt(s.sps[0],n.sps[0])&&(i.dts<s.timelineStartInfo.dts||-1e4<=(i=e.dts-i.dts-i.duration)&&i<=45e3&&(!t||i<r)&&(t=n,r=i));return t?t.gop:null},this.alignGopsAtStart_=function(e){for(var t,i,n,r,a=e.byteLength,s=e.nalCount,o=e.duration,u=t=0;u<l.length&&t<e.length&&(i=l[u],n=e[t],i.pts!==n.pts);)n.pts>i.pts?u++:(t++,a-=n.byteLength,s-=n.nalCount,o-=n.duration);return 0===t?e:t===e.length?null:((r=e.slice(t)).byteLength=a,r.duration=o,r.nalCount=s,r.pts=r[0].pts,r.dts=r[0].dts,r)},this.alignGopsAtEnd_=function(e){for(var t,i,n=l.length-1,r=e.length-1,a=null,s=!1;0<=n&&0<=r;){if(t=l[n],i=e[r],t.pts===i.pts){s=!0;break}t.pts>i.pts?n--:(n===l.length-1&&(a=r),r--)}if(!s&&null===a)return null;if(0===(u=s?r:a))return e;var o=e.slice(u),u=o.reduce(function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e},{byteLength:0,duration:0,nalCount:0});return o.byteLength=u.byteLength,o.duration=u.duration,o.nalCount=u.nalCount,o.pts=o[0].pts,o.dts=o[0].dts,o},this.alignGopsWith=function(e){l=e}}).prototype=new j,(_t=function(e,t){this.numberOfTracks=0,this.metadataStream=t,"undefined"!=typeof(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps?this.keepOriginalTimestamps=e.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,_t.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track,this.pendingBoxes.push(e.boxes)),void("audio"===e.track.type&&(this.audioTrack=e.track,this.pendingBoxes.unshift(e.boxes))))}}).prototype=new j,_t.prototype.flush=function(e){var t,i,n,r=0,a={captions:[],captionStreams:{},metadata:[],info:{}},s=0;if(this.pendingTracks.length<this.numberOfTracks){if("VideoSegmentStream"!==e&&"AudioSegmentStream"!==e)return;if(this.remuxTracks)return;if(0===this.pendingTracks.length)return this.emittedTracks++,void(this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(s=this.videoTrack.timelineStartInfo.pts,St.forEach(function(e){a.info[e]=this.videoTrack[e]},this)):this.audioTrack&&(s=this.audioTrack.timelineStartInfo.pts,Tt.forEach(function(e){a.info[e]=this.audioTrack[e]},this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?a.type=this.pendingTracks[0].type:a.type="combined",this.emittedTracks+=this.pendingTracks.length,e=Q(this.pendingTracks),a.initSegment=new Uint8Array(e.byteLength),a.initSegment.set(e),a.data=new Uint8Array(this.pendingBytes),n=0;n<this.pendingBoxes.length;n++)a.data.set(this.pendingBoxes[n],r),r+=this.pendingBoxes[n].byteLength;for(n=0;n<this.pendingCaptions.length;n++)(t=this.pendingCaptions[n]).startTime=pe(t.startPts,s,this.keepOriginalTimestamps),t.endTime=pe(t.endPts,s,this.keepOriginalTimestamps),a.captionStream
vendor: 6,438 bytes, line 4716
4716s[t.stream]=!0,a.captions.push(t);for(n=0;n<this.pendingMetadata.length;n++)(i=this.pendingMetadata[n]).cueTime=pe(i.pts,s,this.keepOriginalTimestamps),a.metadata.push(i);for(a.metadata.dispatchType=this.metadataStream.dispatchType,this.pendingTracks.length=0,this.videoTrack=null,this.pendingBoxes.length=0,this.pendingCaptions.length=0,this.pendingBytes=0,this.pendingMetadata.length=0,this.trigger("data",a),n=0;n<a.captions.length;n++)t=a.captions[n],this.trigger("caption",t);for(n=0;n<a.metadata.length;n++)i=a.metadata[n],this.trigger("id3Frame",i)}this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},_t.prototype.setRemux=function(e){this.remuxTracks=e},(vt=function(n){var r,a,s=this,i=!0;vt.prototype.init.call(this),this.baseMediaDecodeTime=(n=n||{}).baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var t={};(this.transmuxPipeline_=t).type="aac",t.metadataStream=new Je.MetadataStream,t.aacStream=new bt,t.audioTimestampRolloverStream=new Je.TimestampRolloverStream("audio"),t.timedMetadataTimestampRolloverStream=new Je.TimestampRolloverStream("timed-metadata"),t.adtsStream=new rt,t.coalesceStream=new _t(n,t.metadataStream),t.headOfPipeline=t.aacStream,t.aacStream.pipe(t.audioTimestampRolloverStream).pipe(t.adtsStream),t.aacStream.pipe(t.timedMetadataTimestampRolloverStream).pipe(t.metadataStream).pipe(t.coalesceStream),t.metadataStream.on("timestamp",function(e){t.aacStream.setTimestamp(e.timeStamp)}),t.aacStream.on("data",function(e){"timed-metadata"!==e.type&&"audio"!==e.type||t.audioSegmentStream||(a=a||{timelineStartInfo:{baseMediaDecodeTime:s.baseMediaDecodeTime},codec:"adts",type:"audio"},t.coalesceStream.numberOfTracks++,t.audioSegmentStream=new Ct(a,n),t.audioSegmentStream.on("log",s.getLogTrigger_("audioSegmentStream")),t.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),t.adtsStream.pipe(t.audioSegmentStream).pipe(t.coalesceStream),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r}))}),t.coalesceStream.on("data",this.trigger.bind(this,"data")),t.coalesceStream.on("done",this.trigger.bind(this,"done")),ft(this,t)},this.setupTsPipeline=function(){var i={};(this.transmuxPipeline_=i).type="ts",i.metadataStream=new Je.MetadataStream,i.packetStream=new Je.TransportPacketStream,i.parseStream=new Je.TransportParseStream,i.elementaryStream=new Je.ElementaryStream,i.timestampRolloverStream=new Je.TimestampRolloverStream,i.adtsStream=new rt,i.h264Stream=new wt,i.captionStream=new Je.CaptionStream(n),i.coalesceStream=new _t(n,i.metadataStream),i.headOfPipeline=i.packetStream,i.packetStream.pipe(i.parseStream).pipe(i.elementaryStream).pipe(i.timestampRolloverStream),i.timestampRolloverStream.pipe(i.h264Stream),i.timestampRolloverStream.pipe(i.adtsStream),i.timestampRolloverStream.pipe(i.metadataStream).pipe(i.coalesceStream),i.h264Stream.pipe(i.captionStream).pipe(i.coalesceStream),i.elementaryStream.on("data",function(e){var t;if("metadata"===e.type){for(t=e.tracks.length;t--;)r||"video"!==e.tracks[t].type?a||"audio"!==e.tracks[t].type||((a=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime):(r=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime;r&&!i.videoSegmentStream&&(i.coalesceStream.numberOfTracks++,i.videoSegmentStream=new yt(r,n),i.videoSegmentStream.on("log",s.getLogTrigger_("videoSegmentStream")),i.videoSegmentStream.on("timelineStartInfo",function(e){a&&!n.keepOriginalTimestamps&&(a.timelineStartInfo=e,i.audioSegmentStream.setEarliestDts(e.dts-s.baseMediaDecodeTime))}),i.videoSegmentStream.on("processedGopsInfo",s.trigger.bind(s,"gopInfo")),i.videoSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"videoSegmentTimingInfo")),i.videoSegmentStream.on("baseMediaDecodeTime",function(e){a&&i.audioSegmentStream.setVideoBaseMediaDecodeTime(e)}),i.videoSegmentStream.on("timingInfo",s.trigger.bind(s,"videoTimingInfo")),i.h264Stream.pipe(i.videoSegmentStream).pipe(i.coalesceStream)),a&&!i.audioSegmentStream&&(i.coalesceStream.numberOfTracks++,i.audioSegmentStream=new Ct(a,n),i.audioSegmentStream.on("log",s.getLogTrigger_("audioSegmentStream")),i.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),i.audioSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"audioSegmentTimingInfo")),i.adtsStream.pipe(i.audioSegmentStream).pipe(i.coalesceStream)),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r})}}),i.coalesceStream.on("data",this.trigger.bind(this,"data")),i.coalesceStream.on("id3Frame",function(e){e.dispatchType=i.metadataStream.dispatchType,s.trigger("id3Frame",e)}),i.coalesceStream.on("caption",this.trigger.bind(this,"caption")),i.coalesceStream.on("done",this.trigger.bind(this,"done")),ft(this,i)},this.setBaseMediaDecodeTime=function(e){var t=this.transmuxPipeline_;n.keepOriginalTimestamps||(this.baseMediaDecodeTime=e),a&&(a.timelineStartInfo.dts=void 0,a.timelineStartInfo.pts=void 0,_e(a),t.audioTimestampRolloverStream&&t.audioTimestampRolloverStream.discontinuity()),r&&(t.videoSegmentStream&&(t.videoSegmentStream.gopCache_=[]),r.timelineStartInfo.dts=void 0,r.timelineStartInfo.pts=void 0,_e(r),t.captionStream.reset()),t.timestampRolloverStream&&t.timestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(e){a&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e)},this.setRemux=function(e){var t=this.transmuxPipeline_;n.remux=e,t&&t.coalesceStream&&t.coalesceStream.setRemux(e)},this.alignGopsWith=function(e){r&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e)},this.getLogTrigger_=function(t){var i=this;return function(e){e.stream=t,i.trigger("log",e)}},this.push=function(e){var t;i&&((t=Et(e))&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),i=!1),this.transmuxPipeline_.headOfPipeline.push(e)},this.flush=function(){i=!0,this.transmuxPipeline_.headOfPipeline.flush()},this.endTimeline=function(){this.transmuxPipeline_.headOfPipeline.endTimeline()},this.reset=function(){this.transmuxPipeline_.headOfPipeline&&this.transmuxPipeline_.headOfPipeline.reset()},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset()}}).prototype=new j;function It(e,c){var i=Mt(e,["moof","traf"]),e=Mt(e,["mdat"]),d={},n=[];return e.forEach(function(e,t){t=i[t];n.push({mdat:e,traf:t})}
4716),n.forEach(function(e){var t,i,n,r,a,s=e.mdat,o=e.traf,u=Mt(o,["tfhd"]),l=Ht(u[0]),e=l.trackId,u=Mt(o,["tfdt"]),u=0<u.length?Bt(u[0]).baseMediaDecodeTime:0,o=Mt(o,["trun"]);c===e&&0<o.length&&(o=o,t=u,i=(l=l).defaultSampleDuration||0,n=l.defaultSampleSize||0,r=l.trackId,a=[],o.forEach(function(e){e=jt(e).samples;e.forEach(function(e){void 0===e.duration&&(e.duration=i),void 0===e.size&&(e.size=n),e.trackId=r,e.dts=t,void 0===e.compositionTimeOffset&&(e.compositionTimeOffset=0),"bigint"==typeof t?(e.pts=t+qt.BigInt(e.compositionTimeOffset),t+=qt.BigInt(e.duration)):(e.pts=t+e.compositionTimeOffset,t+=e.duration)}),a=a.concat(e)}),s=function(e,t,i){for(var n,r,a=new DataView(e.buffer,e.byteOffset,e.byteLength),s={logs:[],seiNals:[]},o=0;o+4<e.length;o+=n)if(n=a.getUint32(o),o+=4,!(n<=0))switch(31&e[o]){case 6:var u=e.subarray(o+1,o+1+n),l=function(e,t){for(var i=e,n=0;n<t.length;n++){var r=t[n];if(i<r.size)return r;i-=r.size}return null}(o,t),u={nalUnitType:"sei_rbsp",size:n,data:u,escapedRBSP:Vt(u),trackId:i};if(l)u.pts=l.pts,u.dts=l.dts,r=l;else{if(!r){s.logs.push({level:"warn",message:"We've encountered a nal unit without data at "+o+" for trackId "+i+". See mux.js#223."});break}u.pts=r.pts,u.dts=r.dts}s.seiNals.push(u)}return s}(s,a,e),d[e]||(d[e]={seiNals:[],logs:[]}),d[e].seiNals=d[e].seiNals.concat(s.seiNals),d[e].logs=d[e].logs.concat(s.logs))}),d}function xt(e){var t=31&e[1];return t<<=8,t|=e[2]}function At(e){return!!(64&e[1])}function Pt(e){var t=0;return 1<(48&e[3])>>>4&&(t+=e[4]+1),t}function Lt(e){switch(e){case 5:return"slice_layer_without_partitioning_rbsp_idr";case 6:return"sei_rbsp";case 7:return"seq_parameter_set_rbsp";case 8:return"pic_parameter_set_rbsp";case 9:return"access_unit_delimiter_rbsp";default:return null}}var Dt={Transmuxer:vt,VideoSegmentStream:yt,AudioSegmentStream:Ct,AUDIO_PROPERTIES:Tt,VIDEO_PROPERTIES:St,generateSegmentTimingInfo:gt},e=function(e){return e>>>0},Ot=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),t+=String.fromCharCode(e[2]),t+=String.fromCharCode(e[3])},Rt=e,Mt=function e(t,i){var n,r,a,s=[];if(!i.length)return null;for(n=0;n<t.byteLength;)r=Rt(t[n]<<24|t[n+1]<<16|t[n+2]<<8|t[n+3]),a=Ot(t.subarray(n+4,n+8)),r=1<r?n+r:t.byteLength,a===i[0]&&(1===i.length?s.push(t.subarray(n+8,r)):(a=e(t.subarray(n+8,r),i.slice(1))).length&&(s=s.concat(a))),n=r;return s},Nt=e,Ut=q.getUint64,Bt=function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4))};return 1===t.version?t.baseMediaDecodeTime=Ut(e.subarray(4)):t.baseMediaDecodeTime=Nt(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),t},Ft=function(e){return{isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}},jt=function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]},n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=1&i.flags[2],a=4&i.flags[2],s=1&i.flags[1],o=2&i.flags[1],u=4&i.flags[1],l=8&i.flags[1],c=n.getUint32(4),d=8;for(r&&(i.dataOffset=n.getInt32(d),d+=4),a&&c&&(t={flags:Ft(e.subarray(d,d+4))},d+=4,s&&(t.duration=n.getUint32(d),d+=4),o&&(t.size=n.getUint32(d),d+=4),l&&(1===i.version?t.compositionTimeOffset=n.getInt32(d):t.compositionTimeOffset=n.getUint32(d),d+=4),i.samples.push(t),c--);c--;)t={},s&&(t.duration=n.getUint32(d),d+=4),o&&(t.size=n.getUint32(d),d+=4),u&&(t.flags=Ft(e.subarray(d,d+4)),d+=4),l&&(1===i.version?t.compositionTimeOffset=n.getInt32(d):t.compositionTimeOffset=n.getUint32(d),d+=4),i.samples.push(t);return i},Ht=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:t.getUint32(4)},n=1&i.flags[2],r=2&i.flags[2],a=8&i.flags[2],s=16&i.flags[2],o=32&i.flags[2],u=65536&i.flags[0],l=131072&i.flags[0],e=8;return n&&(e+=4,i.baseDataOffset=t.getUint32(12),e+=4),r&&(i.sampleDescriptionIndex=t.getUint32(e),e+=4),a&&(i.defaultSampleDuration=t.getUint32(e),e+=4),s&&(i.defaultSampleSize=t.getUint32(e),e+=4),o&&(i.defaultSampleFlags=t.getUint32(e)),u&&(i.durationIsEmpty=!0),!n&&l&&(i.baseDataOffsetIsMoof=!0),i},j="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},j="undefined"!=typeof window?window:"undefined"!=typeof j?j:"undefined"!=typeof self?self:{},qt=j,Vt=ke,Wt=Fe.CaptionStream,Gt=function(){var t,r,a,s,o,i,n=!1;this.isInitialized=function(){return n},this.init=function(e){t=new Wt,n=!0,i=!!e&&e.isPartial,t.on("data",function(e){e.startTime=e.startPts/s,e.endTime=e.endPts/s,o.captions.push(e),o.captionStream
4716s[e.stream]=!0}),t.on("log",function(e){o.logs.push(e)})},this.isNewInit=function(e,t){return!(e&&0===e.length||t&&"object"==typeof t&&0===Object.keys(t).length)&&(a!==e[0]||s!==t[a])},this.parse=function(e,t,i){if(!this.isInitialized())return null;if(!t||!i)return null;if(this.isNewInit(t,i))a=t[0],s=i[a];else if(null===a||!s)return r.push(e),null;for(;0<r.length;){var n=r.shift();this.parse(n,t,i)}return(e=function(e,t,i){if(null===t)return null;t=It(e,t)[t]||{};return{seiNals:t.seiNals,logs:t.logs,timescale:i}}(e,a,s))&&e.logs&&(o.logs=o.logs.concat(e.logs)),null!==e&&e.seiNals?(this.pushNals(e.seiNals),this.flushStream(),o):o.logs.length?{logs:o.logs,captions:[],captionStreams:[]}:null},this.pushNals=function(e){if(!this.isInitialized()||!e||0===e.length)return null;e.forEach(function(e){t.push(e)})},this.flushStream=function(){if(!this.isInitialized())return null;i?t.partialFlush():t.flush()},this.clearParsedCaptions=function(){o.captions=[],o.captionStreams={},o.logs=[]},this.resetCaptionStream=function(){if(!this.isInitialized())return null;t.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){r=[],s=a=null,o?this.clearParsedCaptions():o={captions:[],captionStreams:{},logs:[]},this.resetCaptionStream()},this.reset()},zt=e,Xt=function(e){return("00"+e.toString(16)).slice(-2)},Kt=q.getUint64,j=function(e){return Mt(e,["moov","trak"]).reduce(function(e,t){var i,n,r=Mt(t,["tkhd"])[0];return r?(i=r[0],r=zt(r[n=0===i?12:20]<<24|r[1+n]<<16|r[2+n]<<8|r[3+n]),(t=Mt(t,["mdia","mdhd"])[0])?(i=t[0],e[r]=zt(t[n=0===i?12:20]<<24|t[1+n]<<16|t[2+n]<<8|t[3+n]),e):null):null},{})},ke=function(a,e){e=Mt(e,["moof","traf"]).reduce(function(e,t){var i,n=Mt(t,["tfhd"])[0],r=zt(n[4]<<24|n[5]<<16|n[6]<<8|n[7]),n=a[r]||9e4,r=Mt(t,["tfdt"])[0],t=new DataView(r.buffer,r.byteOffset,r.byteLength),t=1===r[0]?Kt(r.subarray(4,12)):t.getUint32(4);return"bigint"==typeof t?i=t/qt.BigInt(n):"number"!=typeof t||isNaN(t)||(i=t/n),e=(i=i<Number.MAX_SAFE_INTEGER?Number(i):i)<e?i:e},1/0);return"bigint"==typeof e||isFinite(e)?e:0},e=function(e){var e=Mt(e,["moov","trak"]),n=[];return e.forEach(function(e){var t=Mt(e,["mdia","hdlr"]),i=Mt(e,["tkhd"]);t.forEach(function(e,t){e=Ot(e.subarray(8,12)),t=i[t];"vide"===e&&(t=0===(t=new DataView(t.buffer,t.byteOffset,t.byteLength)).getUint8(0)?t.getUint32(12):t.getUint32(20),n.push(t))})}),n},Yt=function(e){var t=0===e[0]?12:20;return zt(e[t]<<24|e[1+t]<<16|e[2+t]<<8|e[3+t])},q=function(e){var e=Mt(e,["moov","trak"]),s=[];return e.forEach(function(e){var t={},i=Mt(e,["tkhd"])[0];i&&(i=(n=new DataView(i.buffer,i.byteOffset,i.byteLength)).getUint8(0),t.id=0===i?n.getUint32(12):n.getUint32(20));var n=Mt(e,["mdia","hdlr"])[0];n&&(a=Ot(n.subarray(8,12)),t.type="vide"===a?"video":"soun"===a?"audio":a);var r,a=Mt(e,["mdia","minf","stbl","stsd"])[0];a&&(a=a.subarray(8),t.codec=Ot(a.subarray(4,8)),(a=Mt(a,[t.codec])[0])&&(/^[asm]vc[1-9]$/i.test(t.codec)?(r=a.subarray(78),"avcC"===Ot(r.subarray(4,8))&&11<r.length?(t.codec+=".",t.codec+=Xt(r[9]),t.codec+=Xt(r[10]),t.codec+=Xt(r[11])):t.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(t.codec)?(r=a.subarray(28),"esds"===Ot(r.subarray(4,8))&&20<r.length&&0!==r[19]?(t.codec+="."+Xt(r[19]),t.codec+="."+Xt(r[20]>>>2&63).replace(/^0/,"")):t.codec="mp4a.40.2"):t.codec=t.codec.toLowerCase()));e=Mt(e,["mdia","mdhd"])[0];e&&(t.timescale=Yt(e)),s.push(t)}),s},Qt=ke,$t=q,Jt=Ie,Zt={};Zt.ts={parseType:function(e,t){e=xt(e);return 0===e?"pat":e===t?"pmt":t?"pes":null},parsePat:function(e){var t=At(e),i=4+Pt(e);return t&&(i+=e[i]+1),(31&e[i+10])<<8|e[i+11]},parsePmt:function(e){var t={},i=At(e),n=4+Pt(e);if(i&&(n+=e[n]+1),1&e[n+5]){for(var r=3+((15&e[n+1])<<8|e[n+2])-4,a=12+((15&e[n+10])<<8|e[n+11]);a<r;){var s=n+a;t[(31&e[s+1])<<8|e[s+2]]=e[s],a+=5+((15&e[s+3])<<8|e[s+4])}return t}},parsePayloadUnitStartIndicator:At,parsePesType:function(e,t){switch(t[xt(e)]){case je.H264_STREAM_TYPE:return"video";case je.ADTS_STREAM_TYPE:return"audio";case je.METADATA_STREAM_TYPE:return"timed-metadata";default:return null}},parsePesTime:function(e){if(!At(e))return null;var t=4+Pt(e);if(t>=e.byteLength)return null;var i=null,n=e[t+7];return 192&n&&((i={}).pts=(14&e[t+9])<<27|(255&e[t+10])<<20|(254&e[t+11])<<12|(255&e[t+12])<<5|(254&e[t+13])>>>3,i.pts*=4,i.pts+=(6&e[t+13])>>>1,i.dts=i.pts,64&n&&(i.dts=(14&e[t+14])<<27|(255&e[t+15])<<20|(254&e[t+16])<<12|(255&e[t+17])<<5|(254&e[t+18])>>>3,i.dts*=4,i.dts+=(6&e[t+18])>>>1)),i},videoPacketContainsKeyFrame:function(e){for(var t=4+Pt(e),i=e.subarray(t),n=0,r=0,a=!1;r<i.byteLength-3;r++)if(1===i[r+2]){n=r+5;break}for(;n<i.byteLength;)switch(i[n]){case 0:if(0!==i[n-1]){n+=2;break}if(0!==i[n-2]){n++;break}for(r+3!==n-2&&"slice_layer_without_partitioning_rbsp_idr"===Lt(31&i[r+3])&&(a=!0);1!==i[++n]&&n<i.length;);r=n-2,n+=3;break;case 1:if(0!==i[n-1]||0!==i[n-2]){n+=3;break}"slice_layer_without_partitioning_rbsp_idr"===Lt(31&i[r+3])&&(a=!0),r=n-2,n+=3;break;default:n+=3}return i=i.subarray(r),n-=r,r=0,a=i&&3<i.byteLength&&"slice_layer_without_partitioning_rbsp_idr"===Lt(31&i[r+3])?!0:a}},Zt.aac=dt;function ei(e,t,i){for(var n,r,a,s,o=0,u=188,l=!1;u<=e.byteLength;
4716)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o++,u++;else{if(n=e.subarray(o,u),"pes"===Zt.ts.parseType(n,t.pid)&&(r=Zt.ts.parsePesType(n,t.table),a=Zt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=Zt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)),l)break;o+=188,u+=188}for(o=(u=e.byteLength)-188,l=!1;0<=o;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o--,u--;else{if(n=e.subarray(o,u),"pes"===Zt.ts.parseType(n,t.pid)&&(r=Zt.ts.parsePesType(n,t.table),a=Zt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=Zt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)),l)break;o-=188,u-=188}}function ti(e){var t,i={pid:null,table:null},n={};for(t in!function(e,t){for(var i,n=0,r=188;r<e.byteLength;)if(71!==e[n]||71!==e[r])n++,r++;else{switch(i=e.subarray(n,r),Zt.ts.parseType(i,t.pid)){case"pat":t.pid=Zt.ts.parsePat(i);break;case"pmt":var a=Zt.ts.parsePmt(i);t.table=t.table||{},Object.keys(a).forEach(function(e){t.table[e]=a[e]})}n+=188,r+=188}}(e,i),i.table)if(i.table.hasOwnProperty(t))switch(i.table[t]){case je.H264_STREAM_TYPE:n.video=[],function(e,t,i){for(var n,r,a,s,o,u,l,c,d=0,h=188,p=!1,f={data:[],size:0};h<e.byteLength;)if(71!==e[d]||71!==e[h])d++,h++;else{if(n=e.subarray(d,h),"pes"===Zt.ts.parseType(n,t.pid))if(r=Zt.ts.parsePesType(n,t.table),a=Zt.ts.parsePayloadUnitStartIndicator(n),"video"===r&&(a&&!p&&(s=Zt.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),p=!0),!i.firstKeyFrame)){if(a&&0!==f.size){for(o=new Uint8Array(f.size),u=0;f.data.length;)l=f.data.shift(),o.set(l,u),u+=l.byteLength;!Zt.ts.videoPacketContainsKeyFrame(o)||(c=Zt.ts.parsePesTime(o))&&(i.firstKeyFrame=c,i.firstKeyFrame.type="video"),f.size=0}f.data.push(n),f.size+=n.byteLength}if(p&&i.firstKeyFrame)break;d+=188,h+=188}for(d=(h=e.byteLength)-188,p=!1;0<=d;)if(71!==e[d]||71!==e[h])d--,h--;else{if(n=e.subarray(d,h),"pes"===Zt.ts.parseType(n,t.pid)&&(r=Zt.ts.parsePesType(n,t.table),a=Zt.ts.parsePayloadUnitStartIndicator(n),"video"===r&&a&&(s=Zt.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),p=!0)),p)break;d-=188,h-=188}}(e,i,n),0===n.video.length&&delete n.video;break;case je.ADTS_STREAM_TYPE:n.audio=[],ei(e,i,n),0===n.audio.length&&delete n.audio}return n}var ii=ue,ni=function(e,t){var i,n,r=(Zt.aac.isLikelyAacData(e)?function(e){for(var t,i=!1,n=0,r=null,a=null,s=0,o=0;3<=e.length-o;){switch(Zt.aac.parseType(e,o)){case"timed-metadata":if(e.length-o<10){i=!0;break}if((s=Zt.aac.parseId3TagSize(e,o))>e.length){i=!0;break}null===a&&(t=e.subarray(o,o+s),a=Zt.aac.parseAacTimestamp(t)),o+=s;break;case"audio":if(e.length-o<7){i=!0;break}if((s=Zt.aac.parseAdtsSize(e,o))>e.length){i=!0;break}null===r&&(t=e.subarray(o,o+s),r=Zt.aac.parseSampleRate(t)),n++,o+=s;break;default:o++}if(i)return null}if(null===r||null===a)return null;var u=ii/r;return{audio:[{type:"audio",dts:a,pts:a},{type:"audio",dts:a+1024*n*u,pts:a+1024*n*u}]}}:ti)(e);return r&&(r.audio||r.video)?(e=t,(t=r).audio&&t.audio.length&&("undefined"!=typeof(i=e)&&!isNaN(i)||(i=t.audio[0].dts),t.audio.forEach(function(e){e.dts=Jt(e.dts,i),e.pts=Jt(e.pts,i),e.dtsTime=e.dts/ii,e.ptsTime=e.pts/ii})),t.video&&t.video.length&&("undefined"!=typeof(n=e)&&!isNaN(n)||(n=t.video[0].dts),t.video.forEach(function(e){e.dts=Jt(e.dts,n),e.pts=Jt(e.pts,n),e.dtsTime=e.dts/ii,e.ptsTime=e.pts/ii}),t.firstKeyFrame&&((t=t.firstKeyFrame).dts=Jt(t.dts,n),t.pts=Jt(t.pts,n),t.dtsTime=t.dts/ii,t.ptsTime=t.pts/ii)),r):null},ri=function(){function e(e,t){this.options=t||{},this.self=e,this.init()}var t=e.prototype;return t.init=function(){var i,e;this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new Dt.Transmuxer(this.options),i=this.self,(e=this.transmuxer).on("data",function(e){var t=e.initSegment;e.initSegment={data:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength};t=e.data;e.data=t.buffer,i.postMessage({action:"data",segment:e,byteOffset:t.byteOffset,byteLength:t.byteLength},[e.data])}),e.on("done",function(e){i.postMessage({action:"done"})}),e.on("gopInfo",function(e){i.postMessage({action:"gopInfo",gopInfo:e})}),e.on("videoSegmentTimingInfo",function(e){var t={start:{decode:ce(e.start.dts),presentation:ce(e.start.pts)},end:{decode:ce(e.end.dts),presentation:ce(e.end.pts)},baseMediaDecodeTime:ce(e.baseMediaDecodeTime)};
vendor: 5,685 bytes, line 4716
4716e.prependedContentDuration&&(t.prependedContentDuration=ce(e.prependedContentDuration)),i.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:t})}),e.on("audioSegmentTimingInfo",function(e){var t={start:{decode:ce(e.start.dts),presentation:ce(e.start.pts)},end:{decode:ce(e.end.dts),presentation:ce(e.end.pts)},baseMediaDecodeTime:ce(e.baseMediaDecodeTime)};e.prependedContentDuration&&(t.prependedContentDuration=ce(e.prependedContentDuration)),i.postMessage({action:"audioSegmentTimingInfo",audioSegmentTimingInfo:t})}),e.on("id3Frame",function(e){i.postMessage({action:"id3Frame",id3Frame:e})}),e.on("caption",function(e){i.postMessage({action:"caption",caption:e})}),e.on("trackinfo",function(e){i.postMessage({action:"trackinfo",trackInfo:e})}),e.on("audioTimingInfo",function(e){i.postMessage({action:"audioTimingInfo",audioTimingInfo:{start:ce(e.start),end:ce(e.end)}})}),e.on("videoTimingInfo",function(e){i.postMessage({action:"videoTimingInfo",videoTimingInfo:{start:ce(e.start),end:ce(e.end)}})}),e.on("log",function(e){i.postMessage({action:"log",log:e})})},t.pushMp4Captions=function(e){this.captionParser||(this.captionParser=new Gt,this.captionParser.init());var t=new Uint8Array(e.data,e.byteOffset,e.byteLength),e=this.captionParser.parse(t,e.trackIds,e.timescales);this.self.postMessage({action:"mp4Captions",captions:e&&e.captions||[],logs:e&&e.logs||[],data:t.buffer},[t.buffer])},t.probeMp4StartTime=function(e){var t=e.timescales,e=e.data,t=Qt(t,e);this.self.postMessage({action:"probeMp4StartTime",startTime:t,data:e},[e.buffer])},t.probeMp4Tracks=function(e){var t=e.data,e=$t(t);this.self.postMessage({action:"probeMp4Tracks",tracks:e,data:t},[t.buffer])},t.probeTs=function(e){var t=e.data,i=e.baseStartTime,e="number"!=typeof i||isNaN(i)?void 0:i*ue,i=ni(t,e),e=null;i&&((e={hasVideo:i.video&&2===i.video.length||!1,hasAudio:i.audio&&2===i.audio.length||!1}).hasVideo&&(e.videoStart=i.video[0].ptsTime),e.hasAudio&&(e.audioStart=i.audio[0].ptsTime)),this.self.postMessage({action:"probeTs",result:e,data:t},[t.buffer])},t.clearAllMp4Captions=function(){this.captionParser&&this.captionParser.clearAllCaptions()},t.clearParsedMp4Captions=function(){this.captionParser&&this.captionParser.clearParsedCaptions()},t.push=function(e){e=new Uint8Array(e.data,e.byteOffset,e.byteLength);this.transmuxer.push(e)},t.reset=function(){this.transmuxer.reset()},t.setTimestampOffset=function(e){e=e.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(le(e)))},t.setAudioAppendStart=function(e){this.transmuxer.setAudioAppendStart(Math.ceil(le(e.appendStart)))},t.setRemux=function(e){this.transmuxer.setRemux(e.remux)},t.flush=function(e){this.transmuxer.flush(),self.postMessage({action:"done",type:"transmuxed"})},t.endTimeline=function(){this.transmuxer.endTimeline(),self.postMessage({action:"endedtimeline",type:"transmuxed"})},t.alignGopsWith=function(e){this.transmuxer.alignGopsWith(e.gopsToAlignWith.slice())},e}();self.onmessage=function(e){"init"===e.data.action&&e.data.options?this.messageHandlers=new ri(self,e.data.options):(this.messageHandlers||(this.messageHandlers=new ri(self)),e.data&&e.data.action&&"init"!==e.data.action&&this.messageHandlers[e.data.action]&&this.messageHandlers[e.data.action](e.data))}}))),El=function(e){e.currentTransmux=null,e.transmuxQueue.length&&(e.currentTransmux=e.transmuxQueue.shift(),"function"==typeof e.currentTransmux?e.currentTransmux():Pu(e.currentTransmux))},kl=function(e){Du("reset",e)},Cl=function(e){var t=new wl;t.currentTransmux=null,t.transmuxQueue=[];var i=t.terminate;return t.terminate=function(){return t.currentTransmux=null,t.transmuxQueue.length=0,i.call(t)},t.postMessage({action:"init",options:e}),t},Il=2,xl=-101,Al=-102,Pl=Oo("CodecUtils"),Ll=Oo("PlaylistSelector"),ar=function(){var e=this.useDevicePixelRatio&&window.devicePixelRatio||1;return el(this.playlists.master,this.systemBandwidth,parseInt($u(this.tech_.el(),"width"),10)*e,parseInt($u(this.tech_.el(),"height"),10)*e,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)},Dl=function(n){function e(e,t){var i=n.call(this)||this;if(!e)throw new TypeError("Initialization settings are required");if("function"!=typeof e.currentTime)throw new TypeError("No currentTime getter specified");if(!e.mediaSource)throw new TypeError("No MediaSource specified");return i.bandwidth=e.bandwidth,i.throughput={rate:0,count:0},i.roundTrip=NaN,i.resetStats_(),i.mediaIndex=null,i.partIndex=null,i.hasPlayed_=e.hasPlayed,i.currentTime_=e.currentTime,i.seekable_=e.seekable,i.seeking_=e.seeking,i.duration_=e.duration,i.mediaSource_=e.mediaSource,i.vhs_=e.vhs,i.loaderType_=e.loaderType,i.currentMediaInfo_=void 0,i.startingMediaInfo_=void 0,i.segmentMetadataTrack_=e.segmentMetadataTrack,i.goalBufferLength_=e.goalBufferLength,i.sourceType_=e.sourceType,i.sourceUpdater_=e.sourceUpdater,i.inbandTextTracks_=e.inbandTextTracks,i.state_="INIT",i.timelineChangeController_=e.timelineChangeController,i.shouldSaveSegmentTimingInfo_=!0,i.parse708captions_=e.parse708captions,i.captionServices_=e.captionServices,i.experimentalExactManifestTimings=e.experimentalExactManifestTimings,i.checkBufferTimeout_=null,i.error_=void 0,i.currentTimeline_=-1,i.pendingSegment_=null,i.xhrOptions_=null,i.pendingSegments_=[],i.audioDisabled_=!1,i.isPendingTimestampOffset_=!1,i.gopBuffer_=[],i.timeMapping_=0,i.safeAppend_=11<=tr.browser.IE_VERSION,i.appendInitSegment_={audio:!0,video:!0},i.playlistOfLastInitSegment_={audio:null,video:null},i.callQueue_=[],i.loadQueue_=[],i.metadataQueue_={id3:[],caption:[]},i.waitingOnRemove_=!1,i.quotaExceededErrorRetryTimeout_=null,i.activeInitSegmentId_=null,i.initSegments_={}
vendor: 4,729 bytes, line 4716
4716,i.cacheEncryptionKeys_=e.cacheEncryptionKeys,i.keyCache_={},i.decrypter_=e.decrypter,i.syncController_=e.syncController,i.syncPoint_={segmentIndex:0,time:0},i.transmuxer_=i.createTransmuxer_(),i.triggerSyncInfoUpdate_=function(){return i.trigger("syncinfoupdate")},i.syncController_.on("syncinfoupdate",i.triggerSyncInfoUpdate_),i.mediaSource_.addEventListener("sourceopen",function(){i.isEndOfStream_()||(i.ended_=!1)}),i.fetchAtBuffer_=!1,i.logger_=Oo("SegmentLoader["+i.loaderType_+"]"),Object.defineProperty(ft(i),"state",{get:function(){return this.state_},set:function(e){e!==this.state_&&(this.logger_(this.state_+" -> "+e),this.state_=e,this.trigger("statechange"))}}),i.sourceUpdater_.on("ready",function(){i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),"main"===i.loaderType_&&i.timelineChangeController_.on("pendingtimelinechange",function(){i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),"audio"===i.loaderType_&&i.timelineChangeController_.on("timelinechange",function(){i.hasEnoughInfoToLoad_()&&i.processLoadQueue_(),i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),i}mt(e,n);var t=e.prototype;return t.createTransmuxer_=function(){return Cl({remux:!1,alignGopsAtEnd:this.safeAppend_,keepOriginalTimestamps:!0,parse708captions:this.parse708captions_,captionServices:this.captionServices_})},t.resetStats_=function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0,this.mediaAppends=0},t.dispose=function(){this.trigger("dispose"),this.state="DISPOSED",this.pause(),this.abort_(),this.transmuxer_&&this.transmuxer_.terminate(),this.resetStats_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.syncController_&&this.triggerSyncInfoUpdate_&&this.syncController_.off("syncinfoupdate",this.triggerSyncInfoUpdate_),this.off()},t.setAudio=function(e){this.audioDisabled_=!e,e?this.appendInitSegment_.audio=!0:this.sourceUpdater_.removeAudio(0,this.duration_())},t.abort=function(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)},t.abort_=function(){this.pendingSegment_&&this.pendingSegment_.abortRequests&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.timelineChangeController_.clearPendingTimelineChange(this.loaderType_),this.waitingOnRemove_=!1,window.clearTimeout(this.quotaExceededErrorRetryTimeout_),this.quotaExceededErrorRetryTimeout_=null},t.checkForAbort_=function(e){return"APPENDING"!==this.state||this.pendingSegment_?!this.pendingSegment_||this.pendingSegment_.requestId!==e:(this.state="READY",!0)},t.error=function(e){return"undefined"!=typeof e&&(this.logger_("error occurred:",e),this.error_=e),this.pendingSegment_=null,this.error_},t.endOfStream=function(){this.ended_=!0,this.transmuxer_&&kl(this.transmuxer_),this.gopBuffer_.length=0,this.pause(),this.trigger("ended")},t.buffered_=function(){var e=this.getMediaInfo_();if(!this.sourceUpdater_||!e)return tr.createTimeRanges();if("main"===this.loaderType_){var t=e.hasAudio,i=e.hasVideo,e=e.isMuxed;if(i&&t&&!this.audioDisabled_&&!e)return this.sourceUpdater_.buffered();if(i)return this.sourceUpdater_.videoBuffered()}return this.sourceUpdater_.audioBuffered()},t.initSegmentForMap=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=bu(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes,tracks:e.tracks,timescales:e.timescales}),n||e},t.segmentKey=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=Tu(e),n=this.keyCache_[i];this.cacheEncryptionKeys_&&t&&!n&&e.bytes&&(this.keyCache_[i]=n={resolvedUri:e.resolvedUri,bytes:e.bytes});e={resolvedUri:(n||e).resolvedUri};return n&&(e.bytes=n.bytes),e},t.couldBeginLoading_=function(){return this.playlist_&&!this.paused()},t.load=function(){if(this.monitorBuffer_(),this.playlist_)return"INIT"===this.state&&this.couldBeginLoading_()?this.init_():void(!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY"))},t.init_=function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()},t.playlist=function(e,t){if(void 0===t&&(t={}),e){var i=this.playlist_,n=this.pendingSegment_;this.playlist_=e,this.xhrOptions_=t,"INIT"===this.state&&(e.syncInfo={mediaSequence:e.mediaSequence,time:0},"main"===this.loaderType_&&this.syncController_.setDateTimeMappingForStart(e));var r=null;if(i&&(i.id?r=i.id:i.uri&&(r=i.uri)),this.logger_("playlist update ["+r
4716+" => "+(e.id||e.uri)+"]"),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!i||i.uri!==e.uri)return null!==this.mediaIndex&&(e.endList?this.resyncLoader():this.resetLoader()),this.currentMediaInfo_=void 0,void this.trigger("playlistupdate");t=e.mediaSequence-i.mediaSequence;this.logger_("live window shift ["+t+"]"),null!==this.mediaIndex&&(this.mediaIndex-=t,this.mediaIndex<0?(this.mediaIndex=null,this.partIndex=null):(r=this.playlist_.segments[this.mediaIndex],!this.partIndex||r.parts&&r.parts.length&&r.parts[this.partIndex]||(r=this.mediaIndex,this.logger_("currently processing part (index "+this.partIndex+") no longer exists."),this.resetLoader(),this.mediaIndex=r))),n&&(n.mediaIndex-=t,n.mediaIndex<0?(n.mediaIndex=null,n.partIndex=null):(0<=n.mediaIndex&&(n.segment=e.segments[n.mediaIndex]),0<=n.partIndex&&n.segment.parts&&(n.part=n.segment.parts[n.partIndex]))),this.syncController_.saveExpiredSegmentInfo(i,e)}},t.pause=function(){this.checkBufferTimeout_&&(window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)},t.paused=function(){return null===this.checkBufferTimeout_},t.resetEverything=function(e){this.ended_=!1,this.appendInitSegment_={audio:!0,video:!0},this.resetLoader(),this.remove(0,1/0,e),this.transmuxer_&&(this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.transmuxer_.postMessage({action:"reset"}))},t.resetLoader=function(){this.fetchAtBuffer_=!1,this.resyncLoader()},t.resyncLoader=function(){this.transmuxer_&&kl(this.transmuxer_),this.mediaIndex=null,this.partIndex=null,this.syncPoint_=null,this.isPendingTimestampOffset_=!1,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})},t.remove=function(e,t,i,n){if(void 0===i&&(i=function(){}),void 0===n&&(n=!1),(t=t===1/0?this.duration_():t)<=e)this.logger_("skipping remove because end ${end} is <= start ${start}");else if(this.sourceUpdater_&&this.getMediaInfo_()){var r,a=1,s=function(){0===--a&&i()};for(r in!n&&this.audioDisabled_||(a++,this.sourceUpdater_.removeAudio(e,t,s)),!n&&"main"!==this.loaderType_||(this.gopBuffer_=function(e,t,i,n){for(var r=Math.ceil((t-n)*cl),a=Math.ceil((i-n)*cl),n=e.slice(),s=e.length;s--&&!(e[s].pts<=a););if(-1===s)return n;for(var o=s+1;o--&&!(e[o].pts<=r););return o=Math.max(o,0),n.splice(o,s-o+1),n}(this.gopBuffer_,e,t,this.timeMapping_),a++,this.sourceUpdater_.removeVideo(e,t,s)),this.inbandTextTracks_)il(e,t,this.inbandTextTracks_[r]);il(e,t,this.segmentMetadataTrack_),s()}else this.logger_("skipping remove because no source updater or starting media info")},t.monitorBuffer_=function(){this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),1)},t.monitorBufferTick_=function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&window.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=window.setTimeout(this.monitorBufferTick_.bind(this),500)},t.fillBuffer_=function(){var e;
4716this.sourceUpdater_.updating()||(e=this.chooseNextRequest_())&&("number"==typeof e.timestampOffset&&(this.isPendingTimestampOffset_=!1,this.timelineChangeController_.pendingTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline})),this.loadSegment_(e))},t.isEndOfStream_=function(e,t,i){if(void 0===e&&(e=this.mediaIndex),void 0===t&&(t=this.playlist_),void 0===i&&(i=this.partIndex),!t||!this.mediaSource_)return!1;var n="number"==typeof e&&t.segments[e],e=e+1===t.segments.length,n=!n||!n.parts||i+1===n.parts.length;return t.endList&&"open"===this.mediaSource_.readyState&&e&&n},t.chooseNextRequest_=function(){var e=this.buffered_(),t=Fo(e)||0,i=jo(e,this.currentTime_()),n=!this.hasPlayed_()&&1<=i,r=i>=this.goalBufferLength_(),e=this.playlist_.segments;if(!e.length||n||r)return null;this.syncPoint_=this.syncPoint_||this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_());var a,n={partIndex:null,mediaIndex:null,startOfSegment:null,playlist:this.playlist_,isSyncRequest:Boolean(!this.syncPoint_)};n.isSyncRequest?n.mediaIndex=function(e,t,i){t=t||[];for(var n=[],r=0,a=0;a<t.length;a++){var s=t[a];if(e===s.timeline&&(n.push(a),i<(r+=s.duration)))return a}return 0===n.length?0:n[n.length-1]}(this.currentTimeline_,e,t):null!==this.mediaIndex?(r=e[this.mediaIndex],a="number"==typeof this.partIndex?this.partIndex:-1,n.startOfSegment=r.end||t,r.parts&&r.parts[a+1]?(n.mediaIndex=this.mediaIndex,n.partIndex=a+1):n.mediaIndex=this.mediaIndex+1):(a=(o=fl.getMediaInfoForTime({experimentalExactManifestTimings:this.experimentalExactManifestTimings,playlist:this.playlist_,currentTime:this.fetchAtBuffer_?t:this.currentTime_(),startingPartIndex:this.syncPoint_.partIndex,startingSegmentIndex:this.syncPoint_.segmentIndex,startTime:this.syncPoint_.time})).segmentIndex,s=o.startTime,o=o.partIndex,n.getMediaInfoForTime=this.fetchAtBuffer_?"bufferedEnd "+t:"currentTime "+this.currentTime_(),n.mediaIndex=a,n.startOfSegment=s,n.partIndex=o);var s=e[n.mediaIndex],o=s&&"number"==typeof n.partIndex&&s.parts&&s.parts[n.partIndex];if(!s||"number"==typeof n.partIndex&&!o)return null;"number"!=typeof n.partIndex&&s.parts&&(n.partIndex=0,o=s.parts[0]),i||!o||o.independent||(0===n.partIndex?(o=(i=e[n.mediaIndex-1]).parts&&i.parts.length&&i.parts[i.parts.length-1])&&o.independent&&(--n.mediaIndex,n.partIndex=i.parts.length-1,n.independent="previous segment"):s.parts[n.partIndex-1].independent&&(--n.partIndex,n.independent="previous part"));s=this.mediaSource_&&"ended"===this.mediaSource_.readyState;return n.mediaIndex>=e.length-1&&s&&!this.seeking_()?null:this.generateSegmentInfo_(n)},t.generateSegmentInfo_=function(e){var t=e.independent,i=e.playlist,n=e.mediaIndex,r=e.startOfSegment,a=e.isSyncRequest,s=e.partIndex,o=e.forceTimestampOffset,u=e.getMediaInfoForTime,l=i.segments[n],e="number"==typeof s&&l.parts[s],t={requestId:"segment-loader-"+Math.random(),uri:e&&e.resolvedUri||l.resolvedUri,mediaIndex:n,partIndex:e?s:null,isSyncRequest:a,startOfSegment:r,playlist:i,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:l.timeline,duration:e&&e.duration||l.duration,segment:l,part:e,byteLength:0,transmuxer:this.transmuxer_,getMediaInfoForTime:u,independent:t},o="undefined"!=typeof o?o:this.isPendingTimestampOffset_;t.timestampOffset=this.timestampOffsetForSegment_({segmentTimeline:l.timeline,currentTimeline:this.currentTimeline_,startOfSegment:r,buffered:this.buffered_(),overrideCheck:o});o=Fo(this.sourceUpdater_.audioBuffered());return"number"==typeof o&&(t.audioAppendStart=o-this.sourceUpdater_.audioTimestampOffset()),this.sourceUpdater_.videoBuffered().length&&(t.gopsToAlignWith=function(e,t,i){if("undefined"==typeof t||null===t||!e.length)return[];for(var n=Math.ceil((t-i+3)*cl),r=0;r<e.length&&!(e[r].pts>n);r++);return e.slice(r)}(this.gopBuffer_,this.currentTime_()-this.sourceUpdater_.videoTimestampOffset(),this.timeMapping_)),t},t.timestampOffsetForSegment_=function(e){return i=(t=e).segmentTimeline,n=t.currentTimeline,r=t.startOfSegment,e=t.buffered,t.overrideCheck||i!==n?!(i<n)&&e.length?e.end(e.length-1):r:null;var t,i,n,r},t.earlyAbortWhenNeeded_=function(e){var t,i,n,r,a,s,o,u,l,c,d,h,p;!this.vhs_.tech_.paused()&&this.xhrOptions_.timeout&&this.playlist_.attributes.BANDWIDTH&&(Date.now()-(e.firstBytesReceivedAt||Date.now())<1e3||(t=this.currentTime_(),r=e.bandwidth,a=this.pendingSegment_.duration,p=fl.estimateSegmentRequestTime(a,r,this.playlist_,e.bytesReceived),i=this.buffered_(),n=t,void 0===(e=this.vhs_.tech_.playbackRate())&&
4716(e=1),p<=(e=((i.length?i.end(i.length-1):0)-n)/e-1)||(r={master:this.vhs_.playlists.master,currentTime:t,bandwidth:r,duration:this.duration_(),segmentDuration:a,timeUntilRebuffer:e,currentTimeline:this.currentTimeline_,syncController:this.syncController_},a=r.master,s=r.currentTime,o=r.bandwidth,u=r.duration,l=r.segmentDuration,c=r.timeUntilRebuffer,d=r.currentTimeline,h=r.syncController,a=(r=(a=!(a=(r=a.playlists.filter(function(e){return!fl.isIncompatible(e)})).filter(fl.isEnabled)).length?r.filter(function(e){return!fl.isDisabled(e)}):a).filter(fl.hasAttribute.bind(null,"BANDWIDTH")).map(function(e){var t=h.getSyncPoint(e,u,d,s)?1:2;return{playlist:e,rebufferingImpact:fl.estimateSegmentRequestTime(l,o,e)*t-c}})).filter(function(e){return e.rebufferingImpact<=0}),Ju(a,function(e,t){return Zu(t.playlist,e.playlist)}),(r=a.length?a[0]:(Ju(r,function(e,t){return e.rebufferingImpact-t.rebufferingImpact}),r[0]||null))&&(p=p-e-r.rebufferingImpact,!r.playlist||r.playlist.uri===this.playlist_.uri||p<(e<=hl?1:.5)||(this.bandwidth=r.playlist.attributes.BANDWIDTH*Sl.BANDWIDTH_VARIANCE+1,this.trigger("earlyabort"))))))},t.handleAbort_=function(e){this.logger_("Aborting "+rl(e)),this.mediaRequestsAborted+=1},t.handleProgress_=function(e,t){this.earlyAbortWhenNeeded_(t.stats),this.checkForAbort_(t.requestId)||this.trigger("progress")},t.handleTrackInfo_=function(e,t){this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||this.checkForIllegalMediaSwitch(t)||(function(e,t){if(!e&&!t||!e&&t||e&&!t)return!1;if(e===t)return!0;var i=Object.keys(e).sort(),n=Object.keys(t).sort();if(i.length!==n.length)return!1;for(var r=0;r<i.length;r++){var a=i[r];if(a!==n[r])return!1;if(e[a]!==t[a])return!1}return!0}(this.currentMediaInfo_,t=t||{})||(this.appendInitSegment_={audio:!0,video:!0},this.startingMediaInfo_=t,this.currentMediaInfo_=t,this.logger_("trackinfo update",t),this.trigger("trackinfo")),this.checkForAbort_(e.requestId)||(this.pendingSegment_.trackInfo=t,this.hasEnoughInfoToAppend_()&&this.processCallQueue_()))},t.handleTimingInfo_=function(e,t,i,n){var r;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||((r=this.pendingSegment_)[e=al(t)]=r[e]||{},r[e][i]=n,this.logger_("timinginfo: "+t+" - "+i+" - "+n),this.hasEnoughInfoToAppend_()&&this.processCallQueue_())},t.handleCaptions_=function(e,t){var g,y,v=this;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||(0!==t.length?this.pendingSegment_.hasAppendedData_?(g=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset(),y={},t.forEach(function(e){y[e.stream]=y[e.stream]||{startTime:1/0,captions:[],endTime:0};var t=y[e.stream];t.startTime=Math.min(t.startTime,e.startTime+g),t.endTime=Math.max(t.endTime,e.endTime+g),t.captions.push(e)}),Object.keys(y).forEach(function(e){var t,i,n,r,a,s,o,u,l,c,d=y[e],h=d.startTime,p=d.endTime,f=d.captions,m=v.inbandTextTracks_;v.logger_("adding cues from "+h+" -> "+p+" for "+e),t=m,i=v.vhs_.tech_,t[n=e]||(i.trigger({type:"usage",name:"vhs-608"}),i.trigger({type:"usage",name:"hls-608"}),/^cc708_/.test(r=n)&&(r="SERVICE"+n.split("_")[1]),(o=i.textTracks().getTrackById(r))?t[n]=o:(s=a=n,d=!1,(o=(i.options_.vhs&&i.options_.vhs.captionServices||{})[r])&&(a=o.label,s=o.language,d=o.default),t[n]=i.addRemoteTextTrack({kind:"captions",id:r,default:d,label:a,language:s},!1).track)),il(h,p,m[e]),l=(f={captionArray:f,inbandTextTracks:m,timestampOffset:g}).inbandTextTracks,m=f.captionArray,c=f.timestampOffset,m&&(u=window.WebKitDataCue||window.VTTCue,m.forEach(function(e){var t=e.stream;l[t].addCue(new u(e.startTime+c,e.endTime+c,e.text))}))}),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})):this.metadataQueue_.caption.push(this.handleCaptions_.bind(this,e,t)):this.logger_("SegmentLoader received no captions from a caption event"))},t.handleId3_=function(e,t,i){var n,r,a,s;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||(this.pendingSegment_.hasAppendedData_?(n=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset(),r=this.inbandTextTracks_,a=i,s=this.vhs_.tech_,r.metadataTrack_||(r.metadataTrack_=s.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,r.metadataTrack_.inBandMetadataTrackDispatchType=a),tl({inbandTextTracks:this.inbandTextTracks_,metadataArray:t,timestampOffset:n,videoDuration:this.duration_()})):this.metadataQueue_.id3.push(this.handleId3_.bind(this,e,t,i)))},t.processMetadataQueue_=function(){this.metadataQueue_.id3.forEach(function(e){return e()}),this.metadataQueue_.caption.forEach(function(e){return e()}),this.metadataQueue_.id3=[],this.metadataQueue_.caption=[]},t.processCallQueue_=function(){var e=this.callQueue_;this.callQueue_=[],e.forEach(function(e){return e()})},t.processLoadQueue_=function(){var e=this.loadQueue_;this.loadQueue_=[],e.forEach(function(e){return e()})},t.hasEnoughInfoToLoad_=function(){if("audio"!==this.loaderType_)return!0;var e=this.pendingSegment_;return!!e&&(!this.getCurrentMediaInfo_()||!sl({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:e.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))},t.getCurrentMediaInfo_=function(e){return(e=void 0===e?this.pendingSegment_:e)&&e.trackInfo||this.currentMediaInfo_},t.getMediaInfo_=function(e){return void 0===e&&(e=this.pendingSegment_),this.getCurrentMediaInfo_(e)||this.startingMediaInfo_},t.hasEnoughInfoToAppend_=function(){if(!this.sourceUpdater_.ready())return!1;if(this.waitingOnRemove_||this.quotaExceededErrorRetryTimeout_)return!1;var e=this.pendingSegment_,t=this.getCurrentMediaInfo_();if(!e||!t)return!1;var i=t.hasAudio,n=t.hasVideo,t=t.isMuxed;return!(n&&!e.videoTimingInfo)&&(!(i&&!this.audioDisabled_&&!t&&!e.audioTimingInfo)&&!sl({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:e.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))},t.handleData_=function(e,t){if(this.earlyAbortWhenNeeded_(e.stats),!this.checkForAbort_(e.requestId))if(!this.callQueue_.length&&this.hasEnoughInfoToAppend_()){var i,n=this.pendingSegment_;if(this.setTimeMapping_(n.timeline),this.updateMediaSecondsLoaded_(n.part||n.segment),"closed"!==this.mediaSource_.readyState){if(e.map&&(e.map=this.initSegmentForMap(e.map,!0),n.segment.map=e.map),e.key&&this.segmentKey(e.ke
4716y,!0),n.isFmp4=e.isFmp4,n.timingInfo=n.timingInfo||{},n.isFmp4?(this.trigger("fmp4"),n.timingInfo.start=n[al(t.type)].start):(i=this.getCurrentMediaInfo_(),(i="main"===this.loaderType_&&i&&i.hasVideo)&&(r=n.videoTimingInfo.start),n.timingInfo.start=this.trueSegmentStart_({currentStart:n.timingInfo.start,playlist:n.playlist,mediaIndex:n.mediaIndex,currentVideoTimestampOffset:this.sourceUpdater_.videoTimestampOffset(),useVideoTimingInfo:i,firstVideoFrameTimeForData:r,videoTimingInfo:n.videoTimingInfo,audioTimingInfo:n.audioTimingInfo})),this.updateAppendInitSegmentStatus(n,t.type),this.updateSourceBufferTimestampOffset_(n),n.isSyncRequest){this.updateTimingInfoEnd_(n),this.syncController_.saveSegmentTimingInfo({segmentInfo:n,shouldSaveTimelineMapping:"main"===this.loaderType_});var r=this.chooseNextRequest_();if(r.mediaIndex!==n.mediaIndex||r.partIndex!==n.partIndex)return void this.logger_("sync segment was incorrect, not appending");this.logger_("sync segment was correct, appending")}n.hasAppendedData_=!0,this.processMetadataQueue_(),this.appendData_(n,t)}}else this.callQueue_.push(this.handleData_.bind(this,e,t))},t.updateAppendInitSegmentStatus=function(e,t){"main"!==this.loaderType_||"number"!=typeof e.timestampOffset||e.changedTimestampOffset||(this.appendInitSegment_={audio:!0,video:!0}),this.playlistOfLastInitSegment_[t]!==e.playlist&&(this.appendInitSegment_[t]=!0)},t.getInitSegmentAndUpdateState_=function(e){var t=e.type,i=e.initSegment,n=e.map,r=e.playlist;if(n){e=bu(n);if(this.activeInitSegmentId_===e)return null;i=this.initSegmentForMap(n,!0).bytes,this.activeInitSegmentId_=e}return i&&this.appendInitSegment_[t]?(this.playlistOfLastInitSegment_[t]=r,this.appendInitSegment_[t]=!1,this.activeInitSegmentId_=null,i):null},t.handleQuotaExceededError_=function(e,t){var i=this,n=e.segmentInfo,r=e.type,a=e.bytes,s=this.sourceUpdater_.audioBuffered(),o=this.sourceUpdater_.videoBuffered();1<s.length&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the audio buffer: "+Bo(s).join(", ")),1<o.length&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the video buffer: "+Bo(o).join(", "));var u=s.length?s.start(0):0,l=s.length?s.end(s.length-1):0,c=o.length?o.start(0):0,e=o.length?o.end(o.length-1):0;if(l-u<=1&&e-c<=1)return this.logger_("On QUOTA_EXCEEDED_ERR, single segment too large to append to buffer, triggering an error. Appended byte length: "+a.byteLength+", audio buffer: "+Bo(s).join(", ")+", video buffer: "+Bo(o).join(", ")+", "),this.error({message:"Quota exceeded error with append of a single segment of content",excludeUntil:1/0}),void this.trigger("error");this.waitingOnRemove_=!0,this.callQueue_.push(this.appendToSourceBuffer_.bind(this,{segmentInfo:n,type:r,bytes:a}));a=this.currentTime_()-1;this.logger_("On QUOTA_EXCEEDED_ERR, removing audio/video from 0 to "+a),this.remove(0,a,function(){i.logger_("On QUOTA_EXCEEDED_ERR, retrying append in 1s"),i.waitingOnRemove_=!1,i.quotaExceededErrorRetryTimeout_=window.setTimeout(function(){i.logger_("On QUOTA_EXCEEDED_ERR, re-processing call queue"),i.quotaExceededErrorRetryTimeout_=null,i.processCallQueue_()},1e3)},!0)},t.handleAppendError_=function(e,t){var i=e.segmentInfo,n=e.type,e=e.bytes;t&&(22!==t.code?(this.logger_("Received non QUOTA_EXCEEDED_ERR on append",t),this.error(n+" append of "+e.length+"b failed for segment #"+i.mediaIndex+" in playlist "+i.playlist.id),this.trigger("appenderror")):this.handleQuotaExceededError_({segmentInfo:i,type:n,bytes:e}))},t.appendToSourceBuffer_=function(e){var t,i,n=e.segmentInfo,r=e.type,a=e.initSegment,s=e.data,o=e.bytes;o||(e=[s],s=s.byteLength,a&&(e.unshift(a),s+=a.byteLength),i=0,(e={bytes:s,segments:e}).bytes&&(t=new Uint8Array(e.bytes),e.segments.forEach(function(e){t.set(e,i),i+=e.byteLength})),o=t),this.sourceUpdater_.appendBuffer({segmentInfo:n,type:r,bytes:o},this.handleAppendError_.bind(this,{segmentInfo:n,type:r,bytes:o}))},t.handleSegmentTimingInfo_=function(e,t,i){this.pendingSegment_&&t===this.pendingSegment_.requestId&&((t=this.pendingSegment_.segment)[e=e+"TimingInfo"]||(t[e]={}),t[e].transmuxerPrependedSeconds=i.prependedContentDuration||0,t[e].transmuxedPresentationStart=i.start.presentation,t[e].transmuxedDecodeStart=i.start.decode,t[e].transmuxedPresentationEnd=i.end.presentation,t[e].transmuxedDecodeEnd=i.end.decode,t[e].baseMediaDecodeTime=i.baseMediaDecodeTime)},t.appendData_=function(e,t){var i=t.type,n=t.data;n&&n.byteLength&&("audio"===i&&this.audioDisabled_||(t=this.getInitSegmentAndUpdateState_({type:i,initSegment:t.initSegment,playlist:e.playlist,map:e.isFmp4?e.segment.map:null}),this.appendToSourceBuffer_({segmentInfo:e,type:i,initSegment:t,data:n})))},t.loadSegment_=function(t){var i=this;this.state="WAITING",this.pendingSegment_=t,this.trimBackBuffer_(t),"number"==typeof t.timestampOffset&&this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.hasEnoughInfoToLoad_()?this.updateTransmuxerAndRequestSegment_(t):this.loadQueue_.push(function(){var e=g({},t,{forceTimestampOffset:!0});
4716g(t,i.generateSegmentInfo_(e)),i.isPendingTimestampOffset_=!1,i.updateTransmuxerAndRequestSegment_(t)})},t.updateTransmuxerAndRequestSegment_=function(n){var r=this;this.shouldUpdateTransmuxerTimestampOffset_(n.timestampOffset)&&(this.gopBuffer_.length=0,n.gopsToAlignWith=[],this.timeMapping_=0,this.transmuxer_.postMessage({action:"reset"}),this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:n.timestampOffset}));var e=this.createSimplifiedSegmentObj_(n),t=this.isEndOfStream_(n.mediaIndex,n.playlist,n.partIndex),i=null!==this.mediaIndex,a=n.timeline!==this.currentTimeline_&&0<n.timeline,a=t||i&&a;this.logger_("Requesting "+rl(n)),e.map&&!e.map.bytes&&(this.logger_("going to request init segment."),this.appendInitSegment_={video:!0,audio:!0}),n.abortRequests=Gu({xhr:this.vhs_.xhr,xhrOptions:this.xhrOptions_,decryptionWorker:this.decrypter_,segment:e,abortFn:this.handleAbort_.bind(this,n),progressFn:this.handleProgress_.bind(this),trackInfoFn:this.handleTrackInfo_.bind(this),timingInfoFn:this.handleTimingInfo_.bind(this),videoSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"video",n.requestId),audioSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"audio",n.requestId),captionsFn:this.handleCaptions_.bind(this),isEndOfTimeline:a,endedTimelineFn:function(){r.logger_("received endedtimeline callback")},id3Fn:this.handleId3_.bind(this),dataFn:this.handleData_.bind(this),doneFn:this.segmentRequestFinished_.bind(this),onTransmuxerLog:function(e){var t=e.message,i=e.level,e=e.stream;r.logger_(rl(n)+" logged from transmuxer stream "+e+" as a "+i+": "+t)}})},t.trimBackBuffer_=function(e){var t,i,n,r,r=(t=this.seekable_(),i=this.currentTime_(),n=this.playlist_.targetDuration||10,r=i-Sl.BACK_BUFFER_LENGTH,t.length&&(r=Math.max(r,t.start(0))),Math.min(i-n,r));0<r&&this.remove(0,r)},t.createSimplifiedSegmentObj_=function(e){var t=e.segment,i=e.part,n={resolvedUri:(i||t).resolvedUri,byterange:(i||t).byterange,requestId:e.requestId,transmuxer:e.transmuxer,audioAppendStart:e.audioAppendStart,gopsToAlignWith:e.gopsToAlignWith,part:e.part},i=e.playlist.segments[e.mediaIndex-1];return i&&i.timeline===t.timeline&&(i.videoTimingInfo?n.baseStartTime=i.videoTimingInfo.transmuxedDecodeEnd:i.audioTimingInfo&&(n.baseStartTime=i.audioTimingInfo.transmuxedDecodeEnd)),t.key&&(e=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]),n.key=this.segmentKey(t.key),n.key.iv=e),t.map&&(n.map=this.initSegmentForMap(t.map)),n},t.saveTransferStats_=function(e){this.mediaRequests+=1,e&&(this.mediaBytesTransferred+=e.bytesReceived,this.mediaTransferDuration+=e.roundTripTime)},t.saveBandwidthRelatedStats_=function(e,t){this.pendingSegment_.byteLength=t.bytesReceived,e<1/60?this.logger_("Ignoring segment's bandwidth because its duration of "+e+" is less than the min to record "+1/60):(this.bandwidth=t.bandwidth,this.roundTrip=t.roundTripTime)},t.handleTimeout_=function(){this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,this.trigger("bandwidthupdate")},t.segmentRequestFinished_=function(e,t,i){if(this.callQueue_.length)this.callQueue_.push(this.segmentRequestFinished_.bind(this,e,t,i));else if(this.saveTransferStats_(t.stats),this.pendingSegment_&&t.requestId===this.pendingSegment_.requestId){if(e)return this.pendingSegment_=null,this.state="READY",e.code===Al?void 0:(this.pause(),e.code===xl?void this.handleTimeout_():(this.mediaRequestsErrored+=1,this.error(e),void this.trigger("error")));e=this.pendingSegment_;this.saveBandwidthRelatedStats_(e.duration,t.stats),e.endOfAllRequests=t.endOfAllRequests,i.gopInfo&&(this.gopBuffer_=function(e,t,i){if(!t.length)return e;if(i)return t.slice();for(var n=t[0].pts,r=0;r<e.length&&!(e[r].pts>=n);r++);return e.slice(0,r).concat(t)}(this.gopBuffer_,i.gopInfo,this.safeAppend_)),this.state="APPENDING",this.trigger("appending"),this.waitForAppendsToComplete_(e)}},t.setTimeMapping_=function(e){e=this.syncController_.mappingForTimeline(e);null!==e&&(this.timeMapping_=e)},t.updateMediaSecondsLoaded_=function(e){"number"==typeof e.start&&"number"==typeof e.end?this.mediaSecondsLoaded+=e.end-e.start:this.mediaSecondsLoaded+=e.duration},t.shouldUpdateTransmuxerTimestampOffset_=function(e){return null!==e&&("main"===this.loaderType_&&e!==this.sourceUpdater_.videoTimestampOffset()||!this.audioDisabled_&&e!==this.sourceUpdater_.audioTimestampOffset())},t.trueSegmentStart_=function(e){var t=e.currentStart,i=e.playlist,n=e.mediaIndex,r=e.firstVideoFrameTimeForData,a=e.currentVideoTimestampOffset,s=e.useVideoTimingInfo,o=e.videoTimingInfo,e=e.audioTimingInfo;if("undefined"!=typeof t)return t;if(!s)return e.start;i=i.segments[n-1];return 0!==n&&i&&"undefined"!=typeof i.start&&i.end===r+a?o.start:r},t.waitForAppendsToComplete_=function(e){var t=this.getCurrentMediaInfo_(e);if(!t)return this.error({message:"No starting media returned, likely due to an unsupported media format.",blacklistDuration:1/0}),void this.trigger("error");var i=t.hasAudio,n=t.hasVideo,t=t.isMuxed,n="main"===this.loaderType_&&n,t=!this.audioDisabled_&&i&&!t;if(e.waitingOnAppends=0,!e.hasAppendedData_)return e.timingInfo||"number"!=typeof e.timestampOffset||(this.isPendingTimestampOffset_=!0),e.timingInfo={start:0},e.waitingOnAppends++,this.isPendingTimestampOffset_||(this.updateSourceBufferTimestampOffset_(e),this.processMetadataQueue_()),void this.checkAppendsDone_(e);n&&e.waitingOnAppends++,t&&e.waitingOnAppends++,n&&this.sourceUpdater_.videoQueueCallback(this.checkAppendsDone_.bind(this,e)),t&&this.sourceUpdater_.audioQueueCallback(this.checkAppendsDone_.bind(this,e))},t.checkAppendsDone_=function(e){this.checkForAbort_(e.requestId)||
4716(e.waitingOnAppends--,0===e.waitingOnAppends&&this.handleAppendsDone_())},t.checkForIllegalMediaSwitch=function(e){var t,i,e=(t=this.loaderType_,i=this.getCurrentMediaInfo_(),e=e,"main"===t&&i&&e?e.hasAudio||e.hasVideo?i.hasVideo&&!e.hasVideo?"Only audio found in segment when we expected video. We can't switch to audio only from a stream that had video. To get rid of this message, please add codec information to the manifest.":!i.hasVideo&&e.hasVideo?"Video found in segment when we expected only audio. We can't switch to a stream with video from an audio only stream. To get rid of this message, please add codec information to the manifest.":null:"Neither audio nor video found in segment.":null);return!!e&&(this.error({message:e,blacklistDuration:1/0}),this.trigger("error"),!0)},t.updateSourceBufferTimestampOffset_=function(e){var t;null===e.timestampOffset||"number"!=typeof e.timingInfo.start||e.changedTimestampOffset||"main"!==this.loaderType_||(t=!1,e.timestampOffset-=e.timingInfo.start,e.changedTimestampOffset=!0,e.timestampOffset!==this.sourceUpdater_.videoTimestampOffset()&&(this.sourceUpdater_.videoTimestampOffset(e.timestampOffset),t=!0),e.timestampOffset!==this.sourceUpdater_.audioTimestampOffset()&&(this.sourceUpdater_.audioTimestampOffset(e.timestampOffset),t=!0),t&&this.trigger("timestampoffset"))},t.updateTimingInfoEnd_=function(e){e.timingInfo=e.timingInfo||{};var t=this.getMediaInfo_(),t="main"===this.loaderType_&&t&&t.hasVideo&&e.videoTimingInfo?e.videoTimingInfo:e.audioTimingInfo;t&&(e.timingInfo.end="number"==typeof t.end?t.end:t.start+e.duration)},t.handleAppendsDone_=function(){if(this.pendingSegment_&&this.trigger("appendsdone"),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_;this.updateTimingInfoEnd_(e),this.shouldSaveSegmentTimingInfo_&&this.syncController_.saveSegmentTimingInfo({segmentInfo:e,shouldSaveTimelineMapping:"main"===this.loaderType_});var t=ul(e,this.sourceType_);if(t&&("warn"===t.severity?tr.log.warn(t.message):this.logger_(t.message)),this.recordThroughput_(e),this.pendingSegment_=null,this.state="READY",!e.isSyncRequest||(this.trigger("syncinfoupdate"),e.hasAppendedData_)){this.logger_("Appended "+rl(e)),this.addSegmentMetadataCue_(e),this.fetchAtBuffer_=!0,this.currentTimeline_!==e.timeline&&(this.timelineChangeController_.lastTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline}),"main"!==this.loaderType_||this.audioDisabled_||this.timelineChangeController_.lastTimelineChange({type:"audio",from:this.currentTimeline_,to:e.timeline})),this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate");var i=e.segment,t=e.part,i=i.end&&this.currentTime_()-i.end>3*e.playlist.targetDuration,t=t&&t.end&&this.currentTime_()-t.end>3*e.playlist.partTargetDuration;if(i||t)return this.logger_("bad "+(i?"segment":"part")+" "+rl(e)),void this.resetEverything();null!==this.mediaIndex&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.mediaIndex=e.mediaIndex,this.partIndex=e.partIndex,this.isEndOfStream_(e.mediaIndex,e.playlist,e.partIndex)&&this.endOfStream(),this.trigger("appended"),e.hasAppendedData_&&this.mediaAppends++,this.paused()||this.monitorBuffer_()}else this.logger_("Throwing away un-appended sync request "+rl(e))},t.recordThroughput_=function(e){var t,i;e.duration<1/60?this.logger_("Ignoring segment's throughput because its duration of "+e.duration+" is less than the min to record "+1/60):(t=this.throughput.rate,i=Date.now()-e.endOfAllRequests+1,i=Math.floor(e.byteLength/i*8*1e3),this.throughput.rate+=(i-t)/++this.throughput.count)},t.addSegmentMetadataCue_=function(e){var t,i,n,r;this.segmentMetadataTrack_&&(i=(t=e.segment).start,r=t.end,nl(i)&&nl(r)&&(il(i,r,this.segmentMetadataTrack_),n=window.WebKitDataCue||window.VTTCue,e={custom:t.custom,dateTimeObject:t.dateTimeObject,dateTimeString:t.dateTimeString,bandwidth:e.playlist.attributes.BANDWIDTH,resolution:e.playlist.attributes.RESOLUTION,codecs:e.playlist.attributes.CODECS,byteLength:e.byteLength,uri:e.uri,timeline:e.timeline,playlist:e.playlist.id,start:i,end:r},(r=new n(i,r,JSON.stringify(e))).value=e,this.segmentMetadataTrack_.addCue(r)))},e}(tr.EventTarget);function Ol(){}function Rl(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toUpperCase()})}function Ml(e,t){var i=t[e+"Buffer"];return i&&i.updating||t.queuePending[e]}function Nl(e,t){if(0!==t.queue.length){var i=0,n=t.queue[i];if("mediaSource"!==n.type){if("mediaSource"!==e&&t.ready()&&"closed"!==t.mediaSource.readyState&&!Ml(e,t)){if(n.type!==e){if(null===(i=function(e,t){for(var i=0;i<t.length;i++){var n=t[i];if("mediaSource"===n.type)return null;if(n.type===e)return i}return null}(e,t.queue)))return;n=t.queue[i]}t.queue.splice(i,1),(t.queuePending[e]=n).action(e,t),n.doneFn||(t.queuePending[e]=null,Nl(e,t))}}else t.updating()||"closed"===t.mediaSource.readyState||(t.queue.shift(),n.action(t),n.doneFn&&n.doneFn(),Nl("audio",t),Nl("video",t))}}function Ul(e,t){var i=t[e+"Buffer"],n=Rl(e);i&&(i.removeEventListener("updateend",t["on"+n+"UpdateEnd_"]),i.removeEventListener("error",t["on"+n+"Error_"]),t.codecs[e]=null,t[e+"Buffer"]=null)}function Bl(e,t){return e&&t&&-1!==Array.prototype.indexOf.call(e.sourceBuffers,t)}function Fl(e){var t=e.type,i=e.sourceUpdater,n=e.action,r=e.doneFn,e=e.name;i.queue.push({type:t,action:n,doneFn:r,name:e}),Nl(t,i)}function jl(i,n){return function(e){var t;n.queuePending[i]&&(t=n.queuePending[i].doneFn,n.queuePending[i]=null,t&&t(n[i+"Error_"])),Nl(i,n)}}function Hl(e){return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}function ql(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null)}function Vl(e,t){(t.activePlaylistLoader=e).load()}function Wl(e,t){for(var i=0;i<e.length;i++){if(tu(t,e[i]))return!0;
4716if(e[i].playlists&&Wl(e[i].playlists,t))return!0}return!1}function Gl(a){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){mc[e](e,a)});var e,s=a.mediaTypes,t=a.masterPlaylistLoader,i=a.tech,n=a.vhs,r=a.segmentLoaders,o=r.AUDIO,u=r.main;function l(){s.AUDIO.onTrackChanged(),i.trigger({type:"usage",name:"vhs-audio-change"}),i.trigger({type:"usage",name:"hls-audio-change"})}for(e in["AUDIO","SUBTITLES"].forEach(function(e){var u,l,o,c,t,i,d,h,n,r;s[e].activeGroup=(u=e,l=a,function(t){var e=l.masterPlaylistLoader,i=l.mediaTypes[u].groups,n=e.media();if(!n)return null;var r=null;n.attributes[u]&&(r=i[n.attributes[u]]);var a=Object.keys(i);if(!r)if("AUDIO"===u&&1<a.length&&nu(l.master))for(var s=0;s<a.length;s++){var o=i[a[s]];if(Wl(o,n)){r=o;break}}else i.main?r=i.main:1===a.length&&(r=i[a[0]]);return"undefined"==typeof t?r:null!==t&&r&&r.filter(function(e){return e.id===t.id})[0]||null}),s[e].activeTrack=gc[e](e,a),s[e].onGroupChanged=(o=e,c=a,function(){var e=c.segmentLoaders,t=e[o],i=e.main,n=c.mediaTypes[o],r
4716=n.activeTrack(),a=n.getActiveGroup(),s=n.activePlaylistLoader,e=n.lastGroup_;a&&e&&a.id===e.id||(n.lastGroup_=a,n.lastTrack_=r,ql(t,n),a&&!a.isMasterPlaylist&&(a.playlistLoader?(t.resyncLoader(),Vl(a.playlistLoader,n)):s&&i.resetEverything()))}),s[e].onGroupChanging=(t=e,i=a,function(){var e=i.segmentLoaders[t];i.mediaTypes[t].lastGroup_=null,e.abort(),e.pause()}),s[e].onTrackChanged=(d=e,h=a,function(){var e=h.masterPlaylistLoader,t=h.segmentLoaders,i=t[d],n=t.main,r=h.mediaTypes[d],a=r.activeTrack(),s=r.getActiveGroup(),o=r.activePlaylistLoader,u=r.lastTrack_;if((!u||!a||u.id!==a.id)&&(r.lastGroup_=s,r.lastTrack_=a,ql(i,r),s)){if(s.isMasterPlaylist){if(!a||!u||a.id===u.id)return;var l=h.vhs.masterPlaylistController_,t=l.selectPlaylist();return l.media()===t?void 0:(r.logger_("track change. Switching master audio from "+u.id+" to "+a.id),e.pause(),n.resetEverything(),void l.fastQualityChange_(t))}if("AUDIO"===d){if(!s.playlistLoader)return n.setAudio(!0),void n.resetEverything();i.setAudio(!0),n.setAudio(!1)}o!==s.playlistLoader&&(i.track&&i.track(a),i.resetEverything()),Vl(s.playlistLoader,r)}}),s[e].getActiveGroup=(n=e,r=a.mediaTypes,function(){var e=r[n].activeTrack();return e?r[n].activeGroup(e):null})}),(r=s.AUDIO.activeGroup())&&(r=(r.filter(function(e){return e.default})[0]||r[0]).id,s.AUDIO.tracks[r].enabled=!0,s.AUDIO.onGroupChanged(),s.AUDIO.onTrackChanged(),s.AUDIO.getActiveGroup().playlistLoader?(u.setAudio(!1),o.setAudio(!0)):u.setAudio(!0)),t.on("mediachange",function(){["AUDIO","SUBTITLES"].forEach(function(e){return s[e].onGroupChanged()})}),t.on("mediachanging",function(){["AUDIO","SUBTITLES"].forEach(function(e){return s[e].onGroupChanging()})}),i.audioTracks().addEventListener("change",l),i.remoteTextTracks().addEventListener("change",s.SUBTITLES.onTrackChanged),n.on("dispose",function(){i.audioTracks().removeEventListener("change",l),i.remoteTextTracks().removeEventListener("change",s.SUBTITLES.onTrackChanged)}),i.clearTracks("audio"),s.AUDIO.tracks)i.audioTracks().addTrack(s.AUDIO.tracks[e])}function zl(e,t,i){var n,r,a,s,o=e.masterPlaylistController_,u=o[(e.options_.smoothQualityChange?"smooth":"fast")+"QualityChange_"].bind(o);t.attributes&&(n=t.attributes.RESOLUTION,this.width=n&&n.width,this.height=n&&n.height,this.bandwidth=t.attributes.BANDWIDTH),this.codecs=Yu(o.master(),t),this.playlist=t,this.id=i,this.enabled=(r=e.playlists,a=t.id,s=u,function(e){var t=r.master.playlists[a],i=$o(t),n=Jo(t);return"undefined"==typeof e?n:(e?delete t.disabled:t.disabled=!0,e===n||i||(s(),e?r.trigger("renditionenabled"):r.trigger("renditiondisabled")),e)})}function Xl(t,e){var i=0,n=0,r=tr.mergeOptions(Tc,e);function a(){n&&t.currentTime(n)}function s(e){null!=e&&(n=t.duration()!==1/0&&t.currentTime()||0,t.one("loadedmetadata",a),t.src(e),t.trigger({type:"usage",name:"vhs-error-reload"}),t.trigger({type:"usage",name:"hls-error-reload"}),t.play())}function o(){return Date.now()-i<1e3*r.errorInterval?(t.trigger({type:"usage",name:"vhs-error-reload-canceled"}),void t.trigger({type:"usage",name:"hls-error-reload-canceled"})):r.getSource&&"function"==typeof r.getSource?(i=Date.now(),r.getSource.call(t,s)):void tr.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}function u(){t.off("loadedmetadata",a),t.off("error",o),t.off("dispose",u)}t.ready(function(){t.trigger({type:"usage",name:"vhs-error-reload-initialized"}),t.trigger({type:"usage",name:"hls-error-reload-initialized"})}),t.on("error",o),t.on("dispose",u),t.reloadSourceOnError=function(e){u(),Xl(t,e)}}var Kl,Yl=["video","audio"],Ql=function(n,r,a){return function(t,i){var e=i[t+"Buffer"];if(Bl(i.mediaSource,e)){i.logger_("Appending segment "+r.mediaIndex+"'s "+n.length+" bytes to "+t+"Buffer");try{e.appendBuffer(n)}catch(e){i.logger_("Error with code "+e.code+" "+(22===e.code?"(QUOTA_EXCEEDED_ERR) ":"")+"when appending segment "+r.mediaIndex+" to "+t+"Buffer"),i.queuePending[t]=null,a(e)}}}},$l=function(n,r){return function(t,i){var e=i[t+"Buffer"];if(Bl(i.mediaSource,e)){i.logger_("Removing "+n+" to "+r+" from "+t+"Buffer");try{e.remove(n,r)}catch(e){i.logger_("Remove "+n+" to "+r+" from "+t+"Buffer failed")}}}},Jl=function(n){return function(e,t){var i=t[e+"Buffer"];Bl(t.mediaSource,i)&&(t.logger_("Setting "+e+"timestampOffset to "+n),i.timestampOffset=n)}},Zl=function(i){return function(e,t){i()}},ec=function(t){return function(e){if("open"===e.mediaSource.readyState){e.logger_("Calling mediaSource endOfStream("+(t||"")+")");try{e.mediaSource.endOfStream(t)}catch(e){tr.log.warn("Failed to call media source endOfStream",e)}}}},tc=function(t){return function(e){e.logger_("Setting mediaSource duration to "+t);try{e.mediaSource.duration=t}catch(e){tr.log.warn("Failed to set media source duration",e)}}},ic=function(){return function(t,e){if("open"===e.mediaSource.readyState){var i=e[t+"Buffer"];if(Bl(e.mediaSource,i)){e.logger_("calling abort on "+t+"Buffer");try{i.abort()}catch(e){tr.log.warn("Failed to abort on "+t+"Buffer",e)}}}}},nc=function(n,r){return function(e){var t=Rl(n),i=mr(r);e.logger_("Adding "+n+"Buffer with codec "+r+" to mediaSource");i=e.mediaSource.addSourceBuffer(i);i.addEventListener("updateend",e["on"+t+"UpdateEnd_"]),i.addEventListener("error",e["on"+t+"Error_"]),e.codecs[n]=r,e[n+"Buffer"]=i}},rc=function(i){return function(e){var t=e[i+"Buffer"];if(Ul(i,e),Bl(e.mediaSource,t)){e.logger_("Removing "+i+"Buffer with codec "+e.codecs[i]+" from mediaSource");try{e.mediaSource.removeSourceBuffer(t)}catch(e){tr.log.warn("Failed to removeSourceBuffer "+i+"Buffer",e)}}}},ac=function(r){return function(e,t){var i=t[e+"Buffer"],n=mr(r);Bl(t.mediaSource,i)&&t.codecs[e]!==r&&(t.logger_("changing "+e+"Buffer codec from "+t.codecs[e]+" to "+r),i.changeType(n),t.codecs[e]=r)}},sc=function(i){function e(e){var t=i.call(this)||this;return t.mediaSource=e,t.sourceopenListener_=function(){return Nl("mediaSource",ft(t))},t.mediaSource.addEventListener("sourceopen",t.sourceopenListener_),t.logger_=Oo("SourceUpdater"),t.audioTimestampOffset_=0,t.videoTimestampOffset_=0,t.queue=[],t.queuePending={audio:null,video:null},t.delayedAudioAppendQueue_=[],t.videoAppendQueued_=!1,t.codecs={},t.onVideoUpdateEnd_=jl("video",ft(t)),t.onAudioUpdateEnd_=jl("audio",ft(t)),t.onVideoError_=function(e){t.videoError_=e},t.onAudioError_=function(e){t.audioError_=e},t.createdSourceBuffers_=!1,t.initializedEme_=!1,t.triggeredReady_=!1,t}
vendor: 9,185 bytes, line 4716
4716mt(e,i);var t=e.prototype;return t.initializedEme=function(){this.initializedEme_=!0,this.triggerReady()},t.hasCreatedSourceBuffers=function(){return this.createdSourceBuffers_},t.hasInitializedAnyEme=function(){return this.initializedEme_},t.ready=function(){return this.hasCreatedSourceBuffers()&&this.hasInitializedAnyEme()},t.createSourceBuffers=function(e){this.hasCreatedSourceBuffers()||(this.addOrChangeSourceBuffers(e),this.createdSourceBuffers_=!0,this.trigger("createdsourcebuffers"),this.triggerReady())},t.triggerReady=function(){this.ready()&&!this.triggeredReady_&&(this.triggeredReady_=!0,this.trigger("ready"))},t.addSourceBuffer=function(e,t){Fl({type:"mediaSource",sourceUpdater:this,action:nc(e,t),name:"addSourceBuffer"})},t.abort=function(e){Fl({type:e,sourceUpdater:this,action:ic(e),name:"abort"})},t.removeSourceBuffer=function(e){this.canRemoveSourceBuffer()?Fl({type:"mediaSource",sourceUpdater:this,action:rc(e),name:"removeSourceBuffer"}):tr.log.error("removeSourceBuffer is not supported!")},t.canRemoveSourceBuffer=function(){return!tr.browser.IE_VERSION&&!tr.browser.IS_FIREFOX&&window.MediaSource&&window.MediaSource.prototype&&"function"==typeof window.MediaSource.prototype.removeSourceBuffer},e.canChangeType=function(){return window.SourceBuffer&&window.SourceBuffer.prototype&&"function"==typeof window.SourceBuffer.prototype.changeType},t.canChangeType=function(){return this.constructor.canChangeType()},t.changeType=function(e,t){this.canChangeType()?Fl({type:e,sourceUpdater:this,action:ac(t),name:"changeType"}):tr.log.error("changeType is not supported!")},t.addOrChangeSourceBuffers=function(i){var n=this;if(!i||"object"!=typeof i||0===Object.keys(i).length)throw new Error("Cannot addOrChangeSourceBuffers to undefined codecs");Object.keys(i).forEach(function(e){var t=i[e];if(!n.hasCreatedSourceBuffers())return n.addSourceBuffer(e,t);n.canChangeType()&&n.changeType(e,t)})},t.appendBuffer=function(e,t){var i=this,n=e.segmentInfo,r=e.type,a=e.bytes;if(this.processedAppend_=!0,"audio"===r&&this.videoBuffer&&!this.videoAppendQueued_)return this.delayedAudioAppendQueue_.push([e,t]),void this.logger_("delayed audio append of "+a.length+" until video append");Fl({type:r,sourceUpdater:this,action:Ql(a,n||{mediaIndex:-1},t),doneFn:t,name:"appendBuffer"}),"video"===r&&(this.videoAppendQueued_=!0,this.delayedAudioAppendQueue_.length&&(r=this.delayedAudioAppendQueue_.slice(),this.logger_("queuing delayed audio "+r.length+" appendBuffers"),this.delayedAudioAppendQueue_.length=0,r.forEach(function(e){i.appendBuffer.apply(i,e)})))},t.audioBuffered=function(){return Bl(this.mediaSource,this.audioBuffer)&&this.audioBuffer.buffered||tr.createTimeRange()},t.videoBuffered=function(){return Bl(this.mediaSource,this.videoBuffer)&&this.videoBuffer.buffered||tr.createTimeRange()},t.buffered=function(){var e=Bl(this.mediaSource,this.videoBuffer)?this.videoBuffer:null,t=Bl(this.mediaSource,this.audioBuffer)?this.audioBuffer:null;return t&&!e?this.audioBuffered():e&&!t?this.videoBuffered():function(e,t){var i=null,n=null,r=0,a=[],s=[];if(!(e&&e.length&&t&&t.length))return tr.createTimeRange();for(var o=e.length;o--;)a.push({time:e.start(o),type:"start"}),a.push({time:e.end(o),type:"end"});for(o=t.length;o--;)a.push({time:t.start(o),type:"start"}),a.push({time:t.end(o),type:"end"});for(a.sort(function(e,t){return e.time-t.time}),o=0;o<a.length;o++)"start"===a[o].type?2===++r&&(i=a[o].time):"end"===a[o].type&&1===--r&&(n=a[o].time),null!==i&&null!==n&&(s.push([i,n]),n=i=null);return tr.createTimeRanges(s)}(this.audioBuffered(),this.videoBuffered())},t.setDuration=function(e,t){void 0===t&&(t=Ol),Fl({type:"mediaSource",sourceUpdater:this,action:tc(e),name:"duration",doneFn:t})},t.endOfStream=function(e,t){void 0===t&&(t=Ol),Fl({type:"mediaSource",sourceUpdater:this,action:ec(e="string"!=typeof(e=void 0===e?null:e)?void 0:e),name:"endOfStream",doneFn:t})},t.removeAudio=function(e,t,i){void 0===i&&(i=Ol),this.audioBuffered().length&&0!==this.audioBuffered().end(0)?Fl({type:"audio",sourceUpdater:this,action:$l(e,t),doneFn:i,name:"remove"}):i()},t.removeVideo=function(e,t,i){void 0===i&&(i=Ol),this.videoBuffered().length&&0!==this.videoBuffered().end(0)?Fl({type:"video",sourceUpdater:this,action:$l(e,t),doneFn:i,name:"remove"}):i()},t.updating=function(){return!(!Ml("audio",this)&&!Ml("video",this))},t.audioTimestampOffset=function(e){return"undefined"!=typeof e&&this.audioBuffer&&this.audioTimestampOffset_!==e&&(Fl({type:"audio",sourceUpdater:this,action:Jl(e),name:"timestampOffset"}),this.audioTimestampOffset_=e),this.audioTimestampOffset_},t.videoTimestampOffset=function(e){return"undefined"!=typeof e&&this.videoBuffer&&this.videoTimestampOffset!==e&&(Fl({type:"video",sourceUpdater:this,action:Jl(e),name:"timestampOffset"}),this.videoTimestampOffset_=e),this.videoTimestampOffset_},t.audioQueueCallback=function(e){this.audioBuffer&&Fl({type:"audio",sourceUpdater:this,action:Zl(e),name:"callback"})},t.videoQueueCallback=function(e){this.videoBuffer&&Fl({type:"video",sourceUpdater:this,action:Zl(e),name:"callback"})},t.dispose=function(){var t=this;this.trigger("dispose"),Yl.forEach(function(e){t.abort(e),t.canRemoveSourceBuffer()?t.removeSourceBuffer(e):t[e+"QueueCallback"](function(){return Ul(e,t)})}),this.videoAppendQueued_=!1,this.delayedAudioAppendQueue_.length=0,this.sourceopenListener_&&this.mediaSource.removeEventListener("sourceopen",this.sourceopenListener_),this.off()},e}(tr.EventTarget),oc=new Uint8Array("\n\n".split("").map(function(e){return e.charCodeAt(0)})),uc=function(i){function e(e,t){return(t=i.call(this,e,t=void 0===t?{}:t)||this).mediaSource_=null,t.subtitlesTrack_=null,t.loaderType_="subtitle",t.featuresNativeTextTracks_=e.featuresNativeTextTracks,t.shouldSaveSegmentTimingInfo_=!1,t}mt(e,i);var t=e.prototype;return t.createTransmuxer_=function(){return null},t.buffered_=function(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues||!this.subtitlesTrack_.cues.length)return tr.createTimeRanges();var e=this.subtitlesTrack_.cues,t=e[0].startTime,e=e[e.length-1].startTime;return tr.createTimeRanges([[t,e]])},t.initSegmentForMap=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=bu(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(t=oc.byteLength+e.bytes.byteLength,(t=new Uint8Array(t)).set(e.bytes),t.set(oc,e.bytes.byteLength),this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:t}),n||e},t.couldBeginLoading_=function(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()},t.init_=function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()},t.track=function(e){return"undefined"==typeof e||(this.subtitlesTrack_=e,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_},t.remove=function(e,t){il(e,t,this.subtitlesTrack_)},t.fillBuffer_=function(){var e=this,t=this.chooseNextRequest_();if(t){if(null===this.syncController_.timestampOffsetForTimeline(t.timeline))return this.syncController_.one("timestampoffset",function(){e.state="READY",e.paused()||e.monitorBuffer_()}),void(this.state="WAITING_ON_TIMELINE");this.loadSegment_(t)}},t.timestampOffsetForSegment_=function(){return null},t.chooseNextRequest_=function(){return this.skipEmptySegments_(i.prototype.chooseNextRequest_.call(this))},t.skipEmptySegments_=function(e){for(;e&&e.segment.empty;){if(e.mediaIndex+1>=e.playlist.segments.length){e=null;break}e=this.generateSegmentInfo_({playlist:e.playlist,mediaIndex:e.mediaIndex+1,startOfSegment:e.startOfSegment+e.duration,isSyncRequest:e.isSyncRequest})}return e},t.stopForError=function(e){this.error(e),this.state="READY",this.pause(),this.trigger("error")},t.segmentRequestFinished_=function(e,t,i){var n=this;if(this.subtitlesTrack_){if(this.saveTransferStats_(t.stats),!this.pendingSegment_)return this.state="READY",void(this.mediaRequestsAborted+=1);if(e)return e.code===xl&&this.handleTimeout_(),e.code===Al?this.mediaRequestsAborted+=1:this.mediaRequestsErrored+=1,void this.stopForError(e);var r=this.pendingSegment_;this.saveBandwidthRelatedStats_(r.duration,t.stats),this.state="APPENDING",this.trigger("appending");var a=r.segment;if(a.map&&(a.map.bytes=t.map.bytes),r.bytes=t.bytes,"function"!=typeof window.WebVTT&&this.subtitlesTrack_&&this.subtitlesTrack_.tech_){var s=function(){n.subtitlesTrack_.tech_.off("vttjsloaded",o),n.stopForError({message:"Error loading vtt.js"})},o=function(){n.subtitlesTrack_.tech_.off("vttjserror",s),n.segmentRequestFinished_(e,t,i)};return this.state="WAITING_ON_VTTJS",this.subtitlesTrack_.tech_.one("vttjsloaded",o),void this.subtitlesTrack_.tech_.one("vttjserror",s)}a.requested=!0;try{this.parseVTTCues_(r)}catch(e){return void this.stopForError({message:e.message})}if(this.updateTimeMapping_(r,this.syncController_.timelines[r.timeline],this.playlist_),r.cues.length?r.timingInfo={start:r.cues[0].startTime,end:r.cues[r.cues.length-1].endTime}:r.timingInfo={start:r.startOfSegment,end:r.startOfSegment+r.duration},r.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");r.byteLength=r.bytes.byteLength,this.mediaSecondsLoaded+=a.duration,r.cues.forEac
4716h(function(e){n.subtitlesTrack_.addCue(n.featuresNativeTextTracks_?new window.VTTCue(e.startTime,e.endTime,e.text):e)}),function(t){var e=t.cues;if(e)for(var i=0;i<e.length;i++){for(var n=[],r=0,a=0;a<e.length;a++)e[i].startTime===e[a].startTime&&e[i].endTime===e[a].endTime&&e[i].text===e[a].text&&1<++r&&n.push(e[a]);n.length&&n.forEach(function(e){return t.removeCue(e)})}}(this.subtitlesTrack_),this.handleAppendsDone_()}else this.state="READY"},t.handleData_=function(){},t.updateTimingInfoEnd_=function(){},t.parseVTTCues_=function(t){var e=!1;"function"==typeof window.TextDecoder?i=new window.TextDecoder("utf8"):(i=window.WebVTT.StringDecoder(),e=!0);var i=new window.WebVTT.Parser(window,window.vttjs,i);t.cues=[],t.timestampmap={MPEGTS:0,LOCAL:0},i.oncue=t.cues.push.bind(t.cues),i.ontimestampmap=function(e){t.timestampmap=e},i.onparsingerror=function(e){tr.log.warn("Error encountered when parsing cues: "+e.message)},t.segment.map&&(n=t.segment.map.bytes,e&&(n=Hl(n)),i.parse(n));var n=t.bytes;e&&(n=Hl(n)),i.parse(n),i.flush()},t.updateTimeMapping_=function(e,t,i){var n,r,a=e.segment;t&&(e.cues.length?(r=e.timestampmap,n=r.MPEGTS/cl-r.LOCAL+t.mapping,e.cues.forEach(function(e){e.startTime+=n,e.endTime+=n}),i.syncInfo||(r=e.cues[0].startTime,t=e.cues[e.cues.length-1].startTime,i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:Math.min(r,t-a.duration)})):a.empty=!0)},e}(Dl),lc=[{name:"VOD",run:function(e,t,i,n,r){if(i===1/0)return null;return{time:0,segmentIndex:0,partIndex:null}}},{name:"ProgramDateTime",run:function(e,t,i,n,r){if(!Object.keys(e.timelineToDatetimeMappings).length)return null;var a=null,s=null,o=qo(t);r=r||0;for(var u=0;u<o.length;u++){var l=o[t.endList||0===r?u:o.length-(u+1)],c=l.segment,d=e.timelineToDatetimeMappings[c.timeline];if(d&&c.dateTimeObject){var h=c.dateTimeObject.getTime()/1e3+d;if(c.parts&&"number"==typeof l.partIndex)for(var p=0;p<l.partIndex;p++)h+=c.parts[p].duration;d=Math.abs(r-h);if(null!==s&&(0===d||s<d))break;s=d,a={time:h,segmentIndex:l.segmentIndex,partIndex:l.partIndex}}}return a}},{name:"Segment",run:function(e,t,i,n,r){var a=null,s=null;r=r||0;for(var o=qo(t),u=0;u<o.length;u++){var l=o[t.endList||0===r?u:o.length-(u+1)],c=l.segment,d=l.part&&l.part.start||c&&c.start;if(c.timeline===n&&"undefined"!=typeof d){c=Math.abs(r-d);if(null!==s&&s<c)break;(!a||null===s||c<=s)&&(s=c,a={time:d,segmentIndex:l.segmentIndex,partIndex:l.partIndex})}}return a}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o<t.discontinuityStarts.length;o++){var u=t.discontinuityStarts[o],l=t.discontinuitySequence+o+1,c=e.discontinuities[l];if(c){l=Math.abs(r-c.time);if(null!==s&&s<l)break;(!a||null===s||l<=s)&&(s=l,a={time:c.time,segmentIndex:u,partIndex:null})}}return a}},{name:"Playlist",run:function(e,t,i,n,r){return t.syncInfo?{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence,partIndex:null}:null}}],cc=function(i){function e(e){var t=i.call(this)||this;return t.timelines=[],t.discontinuities=[],t.timelineToDatetimeMappings={},t.logger_=Oo("SyncController"),t}mt(e,i);var t=e.prototype;return t.getSyncPoint=function(e,t,i,n){i=this.runStrategies_(e,t,i,n);return i.length?this.selectSyncPoint_(i,{key:"time",value:n}):null},t.getExpiredTime=function(e,t){if(!e||!e.segments)return null;t=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!t.length)return null;t=this.selectSyncPoint_(t,{key:"segmentIndex",value:0});return 0<t.segmentIndex&&(t.time*=-1),Math.abs(t.time+Ko({defaultDuration:e.targetDuration,durationList:e.segments,startIndex:t.segmentIndex,endIndex:0}))},t.runStrategies_=function(e,t,i,n){for(var r=[],a=0;a<lc.length;a++){var s=lc[a],o=s.run(this,e,t,i,n);o&&(o.strategy=s.name,r.push({strategy:s.name,syncPoint:o}))}return r},t.selectSyncPoint_=function(e,t){for(var i=e[0].syncPoint,n=Math.abs(e[0].syncPoint[t.key]-t.value),r=e[0].strategy,a=1;a<e.length;a++){var s=Math.abs(e[a].syncPoint[t.key]-t.value);s<n&&(n=s,i=e[a].syncPoint,r=e[a].strategy)}return this.logger_("syncPoint for ["+t.key+": "+t.value+"] chosen with strategy ["+r+"]: [time:"+i.time+", segmentIndex:"+i.segmentIndex+("number"==typeof i.partIndex?",partIndex:"+i.partIndex:"")+"]"),i},t.saveExpiredSegmentInfo=function(e,t){var i=t.mediaSequence-e.mediaSequence;if(86400<i)tr.log.warn("Not saving expired segment info. Media sequence gap "+i+" is too large.");else for(var n=i-1;0<=n;n--){var r=e.segments[n];if(r&&"undefined"!=typeof r.start){t.syncInfo={mediaSequence:e.mediaSequence+n,time:r.start}
4716,this.logger_("playlist refresh sync: [time:"+t.syncInfo.time+", mediaSequence: "+t.syncInfo.mediaSequence+"]"),this.trigger("syncinfoupdate");break}}},t.setDateTimeMappingForStart=function(e){var t;this.timelineToDatetimeMappings={},e.segments&&e.segments.length&&e.segments[0].dateTimeObject&&(e=(t=e.segments[0]).dateTimeObject.getTime()/1e3,this.timelineToDatetimeMappings[t.timeline]=-e)},t.saveSegmentTimingInfo=function(e){var t=e.segmentInfo,i=e.shouldSaveTimelineMapping,n=this.calculateSegmentTimeMapping_(t,t.timingInfo,i),e=t.segment;n&&(this.saveDiscontinuitySyncInfo_(t),t.playlist.syncInfo||(t.playlist.syncInfo={mediaSequence:t.playlist.mediaSequence+t.mediaIndex,time:e.start}));t=e.dateTimeObject;e.discontinuity&&i&&t&&(this.timelineToDatetimeMappings[e.timeline]=-t.getTime()/1e3)},t.timestampOffsetForTimeline=function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].time},t.mappingForTimeline=function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].mapping},t.calculateSegmentTimeMapping_=function(e,t,i){var n,r,a=e.segment,s=e.part,o=this.timelines[e.timeline];if("number"==typeof e.timestampOffset)o={time:e.startOfSegment,mapping:e.startOfSegment-t.start},i&&(this.timelines[e.timeline]=o,this.trigger("timestampoffset"),this.logger_("time mapping for timeline "+e.timeline+": [time: "+o.time+"] [mapping: "+o.mapping+"]")),n=e.startOfSegment,r=t.end+o.mapping;else{if(!o)return!1;n=t.start+o.mapping,r=t.end+o.mapping}return s&&(s.start=n,s.end=r),(!a.start||n<a.start)&&(a.start=n),a.end=r,!0},t.saveDiscontinuitySyncInfo_=function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts&&t.discontinuityStarts.length)for(var n=0;n<t.discontinuityStarts.length;n++){var r,a=t.discontinuityStarts[n],s=t.discontinuitySequence+n+1,o=a-e.mediaIndex,u=Math.abs(o);(!this.discontinuities[s]||this.discontinuities[s].accuracy>u)&&(r=void 0,r=o<0?i.start-Ko({defaultDuration:t.targetDuration,durationList:t.segments,startIndex:e.mediaIndex,endIndex:a}):i.end+Ko({defaultDuration:t.targetDuration,durationList:t.segments,startIndex:e.mediaIndex+1,endIndex:a}),this.discontinuities[s]={time:r,accuracy:u})}},t.dispose=function(){this.trigger("dispose"),this.off()},e}(tr.EventTarget),dc=function(t){function e(){var e=t.call(this)||this;return e.pendingTimelineChanges_={},e.lastTimelineChanges_={},e}mt(e,t);var i=e.prototype;return i.clearPendingTimelineChange=function(e){this.pendingTimelineChanges_[e]=null,this.trigger("pendingtimelinechange")},i.pendingTimelineChange=function(e){var t=e.type,i=e.from,e=e.to;return"number"==typeof i&&"number"==typeof e&&(this.pendingTimelineChanges_[t]={type:t,from:i,to:e},this.trigger("pendingtimelinechange")),this.pendingTimelineChanges_[t]},i.lastTimelineChange=function(e){var t=e.type,i=e.from,e=e.to;return"number"==typeof i&&"number"==typeof e&&(this.lastTimelineChanges_[t]={type:t,from:i,to:e},delete this.pendingTimelineChanges_[t],this.trigger("timelinechange")),this.lastTimelineChanges_[t]},i.dispose=function(){this.trigger("dispose"),this.pendingTimelineChanges_={},this.lastTimelineChanges_={},this.off()},e}(tr.EventTarget),hc=x(U(W(function(){function e(e,t,i){return e(i={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&i.path)}},i.exports),i.exports}var t=e(function(e){function n(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}e.exports=function(e,t,i){return t&&n(e.prototype,t),i&&n(e,i),e},e.exports.default=e.exports,e.exports.__esModule=!0}),i=e(function(i){function n(e,t){return i.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},i.exports.default=i.exports,i.exports.__esModule=!0,n(e,t)}i.exports=n,i.exports.default=i.exports,i.exports.__esModule=!0}),n=e(function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,i(e,t)},e.exports.default=e.exports,e.exports.__esModule=!0}),r=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;t=this.listeners[e].indexOf(t);return this.listeners[e]=this.listeners[e].slice(0),this.listeners[e].splice(t,1),-1<t},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n<i;++n)t[n].call(this,arguments[1]);
vendor: 3,809 bytes, lines 4716-4720
4716else for(var r=Array.prototype.slice.call(arguments,1),a=t.length,s=0;s<a;++s)t[s].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}(); 4717 /*! @name aes-decrypter @version 3.1.2 @license Apache-2.0 */ 4718 var c=null,m=function(){function e(e){var t,i,n;c=c||function(){for(var e,t,i,n,r,a,s,o=[[[],[],[],[],[]],[[],[],[],[],[]]],u=o[0],l=o[1],c=u[4],d=l[4],h=[],p=[],f=0;f<256;f++)p[(h[f]=f<<1^283*(f>>7))^f]=f;for(e=t=0;!c[e];e^=i||1,t=p[t]||1)for(s=16843009*h[n=h[i=h[d[c[e]=r=(r=t^t<<1^t<<2^t<<3^t<<4)>>8^255&r^99]=e]]]^65537*n^257*i^16843008*e,a=257*h[r]^16843008*r,f=0;f<4;f++)u[f][e]=a=a<<24^a>>>8,l[f][r]=s=s<<24^s>>>8;for(f=0;f<5;f++)u[f]=u[f].slice(0),l[f]=l[f].slice(0);return o}(),this._tables=[[c[0][0].slice(),c[0][1].slice(),c[0][2].slice(),c[0][3].slice(),c[0][4].slice()],[c[1][0].slice(),c[1][1].slice(),c[1][2].slice(),c[1][3].slice(),c[1][4].slice()]];var r=this._tables[0][4],a=this._tables[1],s=e.length,o=1;if(4!==s&&6!==s&&8!==s)throw new Error("Invalid aes key size");var u=e.slice(0),l=[];for(this._key=[u,l],t=s;t<4*s+28;t++)n=u[t-1],(t%s==0||8===s&&t%s==4)&&(n=r[n>>>24]<<24^r[n>>16&255]<<16^r[n>>8&255]<<8^r[255&n],t%s==0&&(n=n<<8^n>>>24^o<<24,o=o<<1^283*(o>>7))),u[t]=u[t-s]^n;for(i=0;t;i++,t--)n=u[3&i?t:t-4],l[i]=t<=4||i<4?n:a[0][r[n>>>24]]^a[1][r[n>>16&255]]^a[2][r[n>>8&255]]^a[3][r[255&n]]}return e.prototype.decrypt=function(e,t,i,n,r,a){for(var s,o,u,l=this._key[1],c=e^l[0],d=n^l[1],h=i^l[2],p=t^l[3],f=l.length/4-2,m=4,t=this._tables[1],g=t[0],y=t[1],v=t[2],_=t[3],b=t[4],T=0;T<f;T++)s=g[c>>>24]^y[d>>16&255]^v[h>>8&255]^_[255&p]^l[m],o=g[d>>>24]^y[h>>16&255]^v[p>>8&255]^_[255&c]^l[m+1],u=g[h>>>24]^y[p>>16&255]^v[c>>8&255]^_[255&d]^l[m+2],p=g[p>>>24]^y[c>>16&255]^v[d>>8&255]^_[255&h]^l[m+3],m+=4,c=s,d=o,h=u;for(T=0;T<4;T++)r[(3&-T)+a]=b[c>>>24]<<24^b[d>>16&255]<<16^b[h>>8&255]<<8^b[255&p]^l[m++],s=c,c=d,d=h,h=p,p=s},e}(),l=function(t){function e(){var e=t.call(this,r)||this;return e.jobs=[],e.delay=1,e.timeout_=null,e}n(e,t);var i=e.prototype;return i.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},i.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},e}(r),g=function(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24},a=function(){function u(e,t,i,n){var r=u.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new l,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([g(a[o-4]),g(a[o-3]),g(a[o-2]),g(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){ 4719 /*! @name pkcs7 @version 1.0.4 @license Apache-2.0 */ 4720 var e;n(null,(e=s).subarray(0,e.byteLength-e[e.byteLength-1]))})}return u.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=function(e,t,i){for(var n,r,a,s,o=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),u=new m(Array.prototype.slice.call(t)),e=new Uint8Array(e.byteLength),l=new Int32Array(e.buffer),c=i[0],d=i[1],h=i[2],p=i[3],f=0;f<o.length;f+=4)n=g(o[f]),r=g(o[f+1]),a=g(o[f+2]),s=g(o[f+3]),u.decrypt(n,r,a,s,l,f),l[f]=g(l[f]^c),l[f+1]=g(l[f+1]^d),l[f+2]=g(l[f+2]^h),l[f+3]=g(l[f+3]^p),c=n,d=r,h=a,p=s;return e}(t,i,n);r.set(e,t.byteOffset)}},t(u,null,[{key:"STEP",get:function(){return 32e3}}]),u}();self.onmessage=function(e){var r=e.data,t=new Uint8Array(r.encrypted.bytes,r.encrypted.byteOffset,r.encrypted.byteLength),i=new Uint32Array(r.key.bytes,r.key.byteOffset,r.key.byteLength/4),e=new Uint32Array(r.iv.bytes,r.iv.byteOffset,r.iv.byteLength/4);new a(t,i,e,function(e,t){var i,n;self.postMessage((i={source:r.source,decrypted:t},n={}
4720,Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n),[t.buffer])})}}))),pc={AUDIO:function(s,o){return function(){var e=o.segmentLoaders[s],t=o.mediaTypes[s],i=o.blacklistCurrentPlaylist;ql(e,t);var n=t.activeTrack(),e=t.activeGroup(),e=(e.filter(function(e){return e.default})[0]||e[0]).id,r=t.tracks[e];if(n!==r){for(var a in tr.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),t.tracks)t.tracks[a].enabled=t.tracks[a]===r;t.onTrackChanged()}else i({message:"Problem encountered loading the default audio track."})}},SUBTITLES:function(i,n){return function(){var e=n.segmentLoaders[i],t=n.mediaTypes[i];tr.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),ql(e,t);e=t.activeTrack();e&&(e.mode="disabled"),t.onTrackChanged()}}},fc={AUDIO:function(e,t,i){var n,r,a;t&&(n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",pc[e](e,i)))},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",pc[e](e,i))}},mc={AUDIO:function(e,t){var i,n,r=t.vhs,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,d=l.tracks,h=l.logger_,p=t.masterPlaylistLoader,f=nu(p.master);for(i in u[e]&&0!==Object.keys(u[e]).length||(u[e]={main:{default:{default:!0}}},f&&(u[e].main.default.playlists=p.master.playlists)),u[e])for(var m in c[i]||(c[i]=[]),u[e][i]){var g=u[e][i][m],y=void 0,y=f?(h("AUDIO group '"+i+"' label '"+m+"' is a master playlist"),g.isMasterPlaylist=!0,null):"vhs-json"===a&&g.playlists?new yl(g.playlists[0],r,o):g.resolvedUri?new yl(g.resolvedUri,r,o):g.playlists&&"dash"===a?new Tl(g.playlists[0],r,o,p):null,g=tr.mergeOptions({id:m,playlistLoader:y},g);fc[e](e,g.playlistLoader,t),c[i].push(g),"undefined"==typeof d[m]&&(g=new tr.AudioTrack({id:m,kind:(n=void 0,n=(y=g).default?"main":"alternative",n=y.characteristics&&0<=y.characteristics.indexOf("public.accessibility.describes-video")?"main-desc":n),enabled:!1,language:g.language,default:g.default,label:m}),d[m]=g)}s.on("error",pc[e](e,t))},SUBTITLES:function(e,t){var i,n=t.tech,r=t.vhs,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,d=l.tracks,h=t.masterPlaylistLoader;for(i in u[e])for(var p in c[i]||(c[i]=[]),u[e][i])if(!u[e][i][p].forced){var f=u[e][i][p],m=void 0;if("hls"===a)m=new yl(f.resolvedUri,r,o);else if("dash"===a){if(!f.playlists.filter(function(e){return e.excludeUntil!==1/0}).length)return;m=new Tl(f.playlists[0],r,o,h)}else"vhs-json"===a&&(m=new yl(f.playlists?f.playlists[0]:f.resolvedUri,r,o));f=tr.mergeOptions({id:p,playlistLoader:m},f),fc[e](e,f.playlistLoader,t),c[i].push(f),"undefined"==typeof d[p]&&(f=n.addRemoteTextTrack({id:p,kind:"subtitles",default:f.default&&f.autoselect,language:f.language,label:p},!1).track,d[p]=f)}s.on("error",pc[e](e,t))},"CLOSED-CAPTIONS":function(e,t){var i,n=t.tech,r=t.master.mediaGroups,t=t.mediaTypes[e],a=t.groups,s=t.tracks;for(i in r[e])for(var o in a[i]||(a[i]=[]),r[e][i]){var u,l,c=r[e][i][o];/^(?:CC|SERVICE)/.test(c.instreamId)&&(void 0===(l=(u=n.options_.vhs&&n.options_.vhs.captionServices||{})[(l={label:o,language:c.language,instreamId:c.instreamId,default:c.default&&c.autoselect}).instreamId]?tr.mergeOptions(l,u[l.instreamId]):l).default&&delete l.default,a[i].push(tr.mergeOptions({id:o},c)),"undefined"==typeof s[o]&&(l=n.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default,language:l.language,label:l.label},!1).track,s[o]=l))}}},gc={AUDIO:function(i,n){return function(){var e,t=n.mediaTypes[i].tracks;for(e in t)if(t[e].enabled)return t[e];return null}},SUBTITLES:function(i,n){return function(){var e,t=n.mediaTypes[i].tracks;for(e in t)if("showing"===t[e].mode||"hidden"===t[e].mode)return t[e];return null}}},yc=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred","mediaAppends"],vc=function(v){function e(e){var t=v.call(this)||this,i=e.src,n=e.handleManifestRedirects,r=e.withCredentials,a=e.tech,s=e.bandwidth,o=e.externVhs,u=e.useCueTags,l=e.blacklistDuration,c=e.enableLowInitialPlaylist,d=e.s
4720ourceType,h=e.cacheEncryptionKeys,p=e.experimentalBufferBasedABR,f=e.experimentalLeastPixelDiffSelector,m=e.captionServices;if(!i)throw new Error("A non-empty playlist URL or JSON manifest string is required");var g,y=e.maxPlaylistRetries;null!==y&&"undefined"!=typeof y||(y=1/0),Kl=o,t.experimentalBufferBasedABR=Boolean(p),t.experimentalLeastPixelDiffSelector=Boolean(f),t.withCredentials=r,t.tech_=a,t.vhs_=a.vhs,t.sourceType_=d,t.useCueTags_=u,t.blacklistDuration=l,t.maxPlaylistRetries=y,t.enableLowInitialPlaylist=c,t.useCueTags_&&(t.cueTagsTrack_=t.tech_.addTextTrack("metadata","ad-cues"),t.cueTagsTrack_.inBandMetadataTrackDispatchType=""),t.requestOptions_={withCredentials:r,handleManifestRedirects:n,maxPlaylistRetries:y,timeout:null},t.on("error",t.pauseLoading),t.mediaTypes_=(g={},["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){g[e]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:Ol,activeTrack:Ol,getActiveGroup:Ol,onGroupChanged:Ol,onTrackChanged:Ol,lastTrack_:null,logger_:Oo("MediaGroups["+e+"]")}}),g),t.mediaSource=new window.MediaSource,t.handleDurationChange_=t.handleDurationChange_.bind(ft(t)),t.handleSourceOpen_=t.handleSourceOpen_.bind(ft(t)),t.handleSourceEnded_=t.handleSourceEnded_.bind(ft(t)),t.mediaSource.addEventListener("durationchange",t.handleDurationChange_),t.mediaSource.addEventListener("sourceopen",t.handleSourceOpen_),t.mediaSource.addEventListener("sourceended",t.handleSourceEnded_),t.seekable_=tr.createTimeRanges(),t.hasPlayed_=!1,t.syncController_=new cc(e),t.segmentMetadataTrack_=a.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,t.decrypter_=new hc,t.sourceUpdater_=new sc(t.mediaSource),t.inbandTextTracks_={},t.timelineChangeController_=new dc;h={vhs:t.vhs_,parse708captions:e.parse708captions,captionServices:m,mediaSource:t.mediaSource,currentTime:t.tech_.currentTime.bind(t.tech_),seekable:function(){return t.seekable()},seeking:function(){return t.tech_.seeking()},duration:function(){return t.duration()},hasPlayed:function(){return t.hasPlayed_},goalBufferLength:function(){return t.goalBufferLength()},bandwidth:s,syncController:t.syncController_,decrypter:t.decrypter_,sourceType:t.sourceType_,inbandTextTracks:t.inbandTextTracks_,cacheEncryptionKeys:h,sourceUpdater:t.sourceUpdater_,timelineChangeController:t.timelineChangeController_,experimentalExactManifestTimings:e.experimentalExactManifestTimings};t.masterPlaylistLoader_=new("dash"===t.sourceType_?Tl:yl)(i,t.vhs_,t.requestOptions_),t.setupMasterPlaylistLoaderListeners_(),t.mainSegmentLoader_=new Dl(tr.mergeOptions(h,{segmentMetadataTrack:t.segmentMetadataTrack_,loaderType:"main"}),e),t.audioSegmentLoader_=new Dl(tr.mergeOptions(h,{loaderType:"audio"}),e),t.subtitleSegmentLoader_=new uc(tr.mergeOptions(h,{loaderType:"vtt",featuresNativeTextTracks:t.tech_.featuresNativeTextTracks}),e),t.setupSegmentLoaderListeners_(),t.experimentalBufferBasedABR&&(t.masterPlaylistLoader_.one("loadedplaylist",function(){return t.startABRTimer_()}),t.tech_.on("pause",function(){return t.stopABRTimer_()}),t.tech_.on("play",function(){return t.startABRTimer_()})),yc.forEach(function(e){t[e+"_"]=function(e){return this.audioSegmentLoader_[e]+this.mainSegmentLoader_[e]}.bind(ft(t),e)}),t.logger_=Oo("MPC"),t.triggeredFmp4Usage=!1,"none"===t.tech_.preload()?(t.loadOnPlay_=function(){t.loadOnPlay_=null,t.masterPlaylistLoader_.load()},t.tech_.one("play",t.loadOnPlay_)):t.masterPlaylistLoader_.load(),t.timeToLoadedData__=-1,t.mainAppendsToLoadedData__=-1,t.audioAppendsToLoadedData__=-1;e="none"===t.tech_.preload()?"play":"loadstart";return t.tech_.one(e,function(){var e=Date.now();t.tech_.one("loadeddata",function(){t.timeToLoadedData__=Date.now()-e,t.mainAppendsToLoadedData__=t.mainSegmentLoader_.mediaAppends,t.audioAppendsToLoadedData__=t.audioSegmentLoader_.mediaAppends})}),t}mt(e,v);var t=e.prototype;return t.mainAppendsToLoadedData_=function(){return this.mainAppendsToLoadedData__},t.audioAppendsToLoadedData_=function(){return this.audioAppendsToLoadedData__},t.appendsToLoadedData_=function(){var e=this.mainAppendsToLoadedData_(),t=this.audioAppendsToLoadedData_();return-1===e||-1===t?-1:e+t},t.timeToLoadedData_=function(){return this.timeToLoadedData__},t.checkABR_=function(){var e=this.selectPlaylist();e&&this.shouldSwitchToMedia_(e)&&this.switchMedia_(e,"abr")},t.switchMedia_=function(e,t,i){var n=this.media(),r=n&&(n.id||n.uri),n=e.id||e.uri;r&&r!==n&&(this.logger_("switch media "+r+" -> "+n+" from "+t),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-"+t})),this.masterPlaylistLoader_.media(e,i)},t.startABRTimer_=function(){var e=this;this.stopABRTimer_(),this.abrTimer_=window.setInterval(function(){return e.checkABR_()},250)},t.stopABRTimer_=function(){this.tech_.scrubbing&&this.tech_.scrubbing()||(window.clearInterval(this.abrTimer_),this.abrTimer_=null)},t.getAudioTrackPlaylists_=function(){var e=this.master(),t=e&&e.playlists||[];if(!e||!e.mediaGroups||!e.mediaGroups.AUDIO)return t;var i,n=e.mediaGroups.AUDIO,r=Object.keys(n);if(Object.keys(this.mediaTypes_.AUDIO.groups).length)i=this.mediaTypes_.AUDIO.activeTrack();else{var a,s=n.main||r.length&&n[r[0]];for(a in s)if(s[a].default){i={label:a};break}}if(!i)return t;var o,u=[];for(o in n)if(n[o][i.label]){var l=n[o][i.label];if(l.playlists&&l.playlists.length)u.push.apply(u,l.playlists);
4720else if(l.uri)u.push(l);else if(e.playlists.length)for(var c=0;c<e.playlists.length;c++){var d=e.playlists[c];d.attributes&&d.attributes.AUDIO&&d.attributes.AUDIO===o&&u.push(d)}}return u.length?u:t},t.setupMasterPlaylistLoaderListeners_=function(){var i=this;this.masterPlaylistLoader_.on("loadedmetadata",function(){var e=i.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;eu(i.masterPlaylistLoader_.master,i.masterPlaylistLoader_.media())?i.requestOptions_.timeout=0:i.requestOptions_.timeout=t,e.endList&&"none"!==i.tech_.preload()&&(i.mainSegmentLoader_.playlist(e,i.requestOptions_),i.mainSegmentLoader_.load()),Gl({sourceType:i.sourceType_,segmentLoaders:{AUDIO:i.audioSegmentLoader_,SUBTITLES:i.subtitleSegmentLoader_,main:i.mainSegmentLoader_},tech:i.tech_,requestOptions:i.requestOptions_,masterPlaylistLoader:i.masterPlaylistLoader_,vhs:i.vhs_,master:i.master(),mediaTypes:i.mediaTypes_,blacklistCurrentPlaylist:i.blacklistCurrentPlaylist.bind(i)}),i.triggerPresenceUsage_(i.master(),e),i.setupFirstPlay(),!i.mediaTypes_.AUDIO.activePlaylistLoader||i.mediaTypes_.AUDIO.activePlaylistLoader.media()?i.trigger("selectedinitialmedia"):i.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",function(){i.trigger("selectedinitialmedia")})}),this.masterPlaylistLoader_.on("loadedplaylist",function(){i.loadOnPlay_&&i.tech_.off("play",i.loadOnPlay_);var e,t=i.masterPlaylistLoader_.media();if(!t){if(i.excludeUnsupportedVariants_(),!(e=(e=i.enableLowInitialPlaylist?i.selectInitialPlaylist():e)||i.selectPlaylist())||!i.shouldSwitchToMedia_(e))return;if(i.initialMedia_=e,i.switchMedia_(i.initialMedia_,"initial"),!("vhs-json"===i.sourceType_&&i.initialMedia_.segments))return;t=i.initialMedia_}i.handleUpdatedMediaPlaylist(t)}),this.masterPlaylistLoader_.on("error",function(){i.blacklistCurrentPlaylist(i.masterPlaylistLoader_.error)}),this.masterPlaylistLoader_.on("mediachanging",function(){i.mainSegmentLoader_.abort(),i.mainSegmentLoader_.pause()}),this.masterPlaylistLoader_.on("mediachange",function(){var e=i.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;eu(i.masterPlaylistLoader_.master,i.masterPlaylistLoader_.media())?i.requestOptions_.timeout=0:i.requestOptions_.timeout=t,i.mainSegmentLoader_.playlist(e,i.requestOptions_),i.mainSegmentLoader_.load(),i.tech_.trigger({type:"mediachange",bubbles:!0})}),this.masterPlaylistLoader_.on("playlistunchanged",function(){var e=i.masterPlaylistLoader_.media();"playlist-unchanged"!==e.lastExcludeReason_&&i.stuckAtPlaylistEnd_(e)&&(i.blacklistCurrentPlaylist({message:"Playlist no longer updating.",reason:"playlist-unchanged"}),i.tech_.trigger("playliststuck"))}),this.masterPlaylistLoader_.on("renditiondisabled",function(){i.tech_.trigger({type:"usage",name:"vhs-rendition-disabled"}),i.tech_.trigger({type:"usage",name:"hls-rendition-disabled"})}),this.masterPlaylistLoader_.on("renditionenabled",function(){i.tech_.trigger({type:"usage",name:"vhs-rendition-enabled"}),i.tech_.trigger({type:"usage",name:"hls-rendition-enabled"})})},t.handleUpdatedMediaPlaylist=function(e){this.useCueTags_&&this.updateAdCues_(e),this.mainSegmentLoader_.playlist(e,this.requestOptions_),this.updateDuration(!e.endList),this.tech_.paused()||(this.mainSegmentLoader_.load(),this.audioSegmentLoader_&&this.audioSegmentLoader_.load())},t.triggerPresenceUsage_=function(e,t){var i,n=e.mediaGroups||{},r=!0,e=Object.keys(n.AUDIO);for(i in n.AUDIO)for(var a in n.AUDIO[i])n.AUDIO[i][a].uri||(r=!1);r&&(this.tech_.trigger({type:"usage",name:"vhs-demuxed"}),this.tech_.trigger({type:"usage",name:"hls-demuxed"})),Object.keys(n.SUBTITLES).length&&(this.tech_.trigger({type:"usage",name:"vhs-webvtt"}),this.tech_.trigger({type:"usage",name:"hls-webvtt"})),Kl.Playlist.isAes(t)&&(this.tech_.trigger({type:"usage",name:"vhs-aes"}),this.tech_.trigger({type:"usage",name:"hls-aes"})),e.length&&1<Object.keys(n.AUDIO[e[0]]).length&&(this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.tech_.trigger({type:"usage",name:"hls-alternate-audio"})),this.useCueTags_&&(this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"}),this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"}))},t.shouldSwitchToMedia_=function(e){var t=this.masterPlaylistLoader_.media()||this.masterPlaylistLoader_.pen
4720dingMedia_,i=this.tech_.currentTime(),n=this.bufferLowWaterLine(),r=this.bufferHighWaterLine();return function(e){var t=e.currentPlaylist,i=e.buffered,n=e.currentTime,r=e.nextPlaylist,a=e.bufferLowWaterLine,s=e.bufferHighWaterLine,o=e.duration,u=e.experimentalBufferBasedABR,l=e.log;if(!r)return tr.log.warn("We received no playlist to switch to. Please check your stream."),!1;var c="allowing switch "+(t&&t.id||"null")+" -> "+r.id;if(!t)return l(c+" as current playlist is not set"),!0;if(r.id===t.id)return!1;e=Boolean(Mo(i,n).length);if(!t.endList)return e||"number"!=typeof t.partTargetDuration?(l(c+" as current playlist is live"),!0):(l("not "+c+" as current playlist is live llhls, but currentTime isn't in buffered."),!1);i=jo(i,n),n=u?Sl.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:Sl.MAX_BUFFER_LOW_WATER_LINE;if(o<n)return l(c+" as duration < max low water line ("+o+" < "+n+")"),!0;n=r.attributes.BANDWIDTH,r=t.attributes.BANDWIDTH;if(n<r&&(!u||i<s)){t=c+" as next bandwidth < current bandwidth ("+n+" < "+r+")";return u&&(t+=" and forwardBuffer < bufferHighWaterLine ("+i+" < "+s+")"),l(t),!0}if((!u||r<n)&&a<=i){a=c+" as forwardBuffer >= bufferLowWaterLine ("+i+" >= "+a+")";return u&&(a+=" and next bandwidth > current bandwidth ("+n+" > "+r+")"),l(a),!0}return l("not "+c+" as no switching criteria met"),!1}({buffered:this.tech_.buffered(),currentTime:i,currentPlaylist:t,nextPlaylist:e,bufferLowWaterLine:n,bufferHighWaterLine:r,duration:this.duration(),experimentalBufferBasedABR:this.experimentalBufferBasedABR,log:this.logger_})},t.setupSegmentLoaderListeners_=function(){var t=this;this.experimentalBufferBasedABR||(this.mainSegmentLoader_.on("bandwidthupdate",function(){var e=t.selectPlaylist();t.shouldSwitchToMedia_(e)&&t.switchMedia_(e,"bandwidthupdate"),t.tech_.trigger("bandwidthupdate")}),this.mainSegmentLoader_.on("progress",function(){t.trigger("progress")})),this.mainSegmentLoader_.on("error",function(){t.blacklistCurrentPlaylist(t.mainSegmentLoader_.error())}),this.mainSegmentLoader_.on("appenderror",function(){t.error=t.mainSegmentLoader_.error_,t.trigger("error")}),this.mainSegmentLoader_.on("syncinfoupdate",function(){t.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("timestampoffset",function(){t.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"}),t.tech_.trigger({type:"usage",name:"hls-timestamp-offset"})}),this.audioSegmentLoader_.on("syncinfoupdate",function(){t.onSyncInfoUpdate_()}),this.audioSegmentLoader_.on("appenderror",function(){t.error=t.audioSegmentLoader_.error_,t.trigger("error")}),this.mainSegmentLoader_.on("ended",function(){t.logger_("main segment loader ended"),t.onEndOfStream()}),this.mainSegmentLoader_.on("earlyabort",function(e){t.experimentalBufferBasedABR||(t.delegateLoaders_("all",["abort"]),t.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120))});function e(){if(!t.sourceUpdater_.hasCreatedSourceBuffers())return t.tryToCreateSourceBuffers_();var e=t.getCodecsOrExclude_();e&&t.sourceUpdater_.addOrChangeSourceBuffers(e)}this.mainSegmentLoader_.on("trackinfo",e),this.audioSegmentLoader_.on("trackinfo",e),this.mainSegmentLoader_.on("fmp4",function(){t.triggeredFmp4Usage||(t.tech_.trigger({type:"usage",name:"vhs-fmp4"}),t.tech_.trigger({type:"usage",name:"hls-fmp4"}),t.triggeredFmp4Usage=!0)}),this.audioSegmentLoader_.on("fmp4",function(){t.triggeredFmp4Usage||(t.tech_.trigger({type:"usage",name:"vhs-fmp4"}),t.tech_.trigger({type:"usage",name:"hls-fmp4"}),t.triggeredFmp4Usage=!0)}),this.audioSegmentLoader_.on("ended",function(){t.logger_("audioSegmentLoader ended"),t.onEndOfStream()})},t.mediaSecondsLoaded_=function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)},t.load=function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()},t.smoothQualityChange_=function(e){void 0===e&&(e=this.selectPlaylist()),this.fastQualityChange_(e)},t.fastQualityChange_=function(e){var t=this;(e=void 0===e?this.selectPlaylist():e)!==this.masterPlaylistLoader_.media()?(this.switchMedia_(e,"fast-quality"),this.mainSegmentLoader_.resetEverything(function(){tr.browser.IE_VERSION||tr.browser.IS_EDGE?t.tech_.setCurrentTime(t.tech_.currentTime()+.04):t.tech_.setCurrentTime(t.tech_.currentTime())})):this.logger_("skipping fastQualityChange because new media is same as old")},t.play=function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()<e.start(0)?this.tech_.setCurrentTime(e.end(e.length-1)):void 0}},t.setupFirstPlay=function(){var e=this,t=this.masterPlaylistLoader_.media();if(!t||this.tech_.paused()||this.hasPlayed_)return!1;if(!t.endList){var i=this.seekable();if(!i.length)return!1;if(tr.browser.IE_VERSION&&0===this.tech_.readyState())return this.tech_.one("loadedmetadata",function(){e.trigger("firstplay"),e.tech_.setCurrentTime(i.end(0)),e.hasPlayed_=!0}),!1;this.trigger("firstplay"),this.tech_.setCurrentTime(i.end(0))}return this.hasPlayed_=!0,this.load(),!0},t.handleSourceOpen_=function(){var e;this.tryToCreateSourceBuffers_(),!this.tech_.autoplay()||"undefined"!=typeof(e=this.tech_.play())&&"function"==typeof e.then&&e.then(null,function(e){}),this.trigger("sourceopen")},t.handleSourceEnded_=function(){var e,t;!this.inbandTextTracks_.metadataTrack_||(e=this.inbandTextTracks_.metadataTrack_.cues)&&e.length&&(t=this.duration(),e[e.length-1].endTime=isNaN(t)||Math.abs(t)===1/0?Number.MAX_VALUE:t)},t.handleDurationChange_=function(){this.tech_.trigger("durationchange")},t.onEndOfStream=function(){var e,t=this.mainSegmentLoader_.ended_;(t=this.mediaTypes_.AUDIO.activePlaylistLoader?((e=this.mainSegmentLoader_.getCurrentMediaInfo_())&&!e.hasVideo||t)&&this.audioSegmentLoader_.ended_:t)&&(this.stopABRTimer_(),this.sourceUpdater_.endOfStream())},t.stuckAtPlaylistEnd_=function(e){if(!this.seekable().length)return!1;var t=this.syncController_.getExpiredTime(e,this.duration());if(null===t)return!1;var i=Kl.Playlist.playlistEnd(e,t),e=this.tech_.currentTime(),t=this.tech_.buffered();if(!t.length)return i-e<=.1;t=t.end(t.length-1);return t-e<=.1&&i-t<=.1},t.blacklistCurrentPlaylist=function(e,t){var i=(e=void 0===e?{}:e).playlist||this.masterPlaylistLoader_.media();
4720if(t=t||e.blacklistDuration||this.blacklistDuration,!i)return this.error=e,void("open"!==this.mediaSource.readyState?this.trigger("error"):this.sourceUpdater_.endOfStream("network"));i.playlistErrors_++;var n,r=this.masterPlaylistLoader_.master.playlists,a=r.filter(Jo),s=1===a.length&&a[0]===i;if(1===r.length&&t!==1/0)return tr.log.warn("Problem encountered with playlist "+i.id+". Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.masterPlaylistLoader_.load(s);s&&(n=!1,r.forEach(function(e){var t;e===i||"undefined"!=typeof(t=e.excludeUntil)&&t!==1/0&&(n=!0,delete e.excludeUntil)}),n&&(tr.log.warn("Removing other playlists from the exclusion list because the last rendition is about to be excluded."),this.tech_.trigger("retryplaylist"))),a=i.playlistErrors_>this.maxPlaylistRetries?1/0:Date.now()+1e3*t,i.excludeUntil=a,e.reason&&(i.lastExcludeReason_=e.reason),this.tech_.trigger("blacklistplaylist"),this.tech_.trigger({type:"usage",name:"vhs-rendition-blacklisted"}),this.tech_.trigger({type:"usage",name:"hls-rendition-blacklisted"});r=this.selectPlaylist();if(!r)return this.error="Playback cannot continue. No available working or supported playlists.",void this.trigger("error");t=e.internal?this.logger_:tr.log.warn,a=e.message?" "+e.message:"";t((e.internal?"Internal problem":"Problem")+" encountered with playlist "+i.id+"."+a+" Switching to playlist "+r.id+"."),r.attributes.AUDIO!==i.attributes.AUDIO&&this.delegateLoaders_("audio",["abort","pause"]),r.attributes.SUBTITLES!==i.attributes.SUBTITLES&&this.delegateLoaders_("subtitle",["abort","pause"]),this.delegateLoaders_("main",["abort","pause"]);a=r.targetDuration/2*1e3||5e3,a="number"==typeof r.lastRequest&&Date.now()-r.lastRequest<=a;return this.switchMedia_(r,"exclude",s||a)},t.pauseLoading=function(){this.delegateLoaders_("all",["abort","pause"]),this.stopABRTimer_()},t.delegateLoaders_=function(i,e){var n=this,r=[],t="all"===i;!t&&"main"!==i||r.push(this.masterPlaylistLoader_);var a=[];!t&&"audio"!==i||a.push("AUDIO"),!t&&"subtitle"!==i||(a.push("CLOSED-CAPTIONS"),a.push("SUBTITLES")),a.forEach(function(e){e=n.mediaTypes_[e]&&n.mediaTypes_[e].activePlaylistLoader;e&&r.push(e)}),["main","audio","subtitle"].forEach(function(e){var t=n[e+"SegmentLoader_"];!t||i!==e&&"all"!==i||r.push(t)}),r.forEach(function(t){return e.forEach(function(e){"function"==typeof t[e]&&t[e]()})})},t.setCurrentTime=function(e){var t=Mo(this.tech_.buffered(),e);return this.masterPlaylistLoader_&&this.masterPlaylistLoader_.media()&&this.masterPlaylistLoader_.media().segments?t&&t.length?e:(this.mainSegmentLoader_.resetEverything(),this.mainSegmentLoader_.abort(),this.mediaTypes_.AUDIO.activePlaylistLoader&&(this.audioSegmentLoader_.resetEverything(),this.audioSegmentLoader_.abort()),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&(this.subtitleSegmentLoader_.resetEverything(),this.subtitleSegmentLoader_.abort()),void this.load()):0},t.duration=function(){if(!this.masterPlaylistLoader_)return 0;var e=this.masterPlaylistLoader_.media();return e?e.endList?this.mediaSource?this.mediaSource.duration:Kl.Playlist.duration(e):1/0:0},t.seekable=function(){return this.seekable_},t.onSyncInfoUpdate_=function(){var e;if(this.masterPlaylistLoader_){var t=this.masterPlaylistLoader_.media();if(t){var i=this.syncController_.getExpiredTime(t,this.duration());if(null!==i){var n,r,a=this.masterPlaylistLoader_.master,s=Kl.Playlist.seekable(t,i,Kl.Playlist.liveEdgeDelay(a,t));if(0!==s.length){if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(t=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),null===(i=this.syncController_.getExpiredTime(t,this.duration())))return;if(0===(e=Kl.Playlist.seekable(t,i,Kl.Playlist.liveEdgeDelay(a,t))).length)return}this.seekable_&&this.seekable_.length&&(n=this.seekable_.end(0),r=this.seekable_.start(0)),!e||e.start(0)>s.end(0)||s.start(0)>e.end(0)?this.seekable_=s:this.seekable_=tr.createTimeRanges([[(e.start(0)>s.start(0)?e:s).start(0),(e.end(0)<s.end(0)?e:s).end(0)]]),this.seekable_&&this.seekable_.length&&this.seekable_.end(0)===n&&this.seekable_.start(0)===r||(this.logger_("seekable updated ["+Uo(this.seekable_)+"]"),this.tech_.trigger("seekablechanged"))}}}}},t.updateDuration=function(e){if(this.updateDuration_&&(this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.updateDuration_=null),"open"!==this.mediaSource.readyState)return this.updateDuration_=this.updateDuration.bind(this,e),void this.mediaSource.addEventListener("sourceopen",this.updateDuration_);if(e){var t=this.seekable();return t.length?void((isNaN(this.mediaSource.duration)||this.mediaSource.duration<t.end(t.length-1))&&this.sourceUpdater_.setDuration(t.end(t.length-1))):void 0}e=this.tech_.buffered(),t=Kl.Playlist.duration(this.masterPlaylistLoader_.media());0<e.length&&(t=Math.max(t,e.end(e.length-1))),this.mediaSource.duration!==t&&this.sourceUpdater_.setDuration(t)}
4720,t.dispose=function(){var n=this;this.trigger("dispose"),this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach(function(e){var t,i=n.mediaTypes_[e].groups;for(t in i)i[t].forEach(function(e){e.playlistLoader&&e.playlistLoader.dispose()})}),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off()},t.master=function(){return this.masterPlaylistLoader_.master},t.media=function(){return this.masterPlaylistLoader_.media()||this.initialMedia_},t.areMediaTypesKnown_=function(){var e=!!this.mediaTypes_.AUDIO.activePlaylistLoader,t=!!this.mainSegmentLoader_.getCurrentMediaInfo_(),e=!e||!!this.audioSegmentLoader_.getCurrentMediaInfo_();return t&&e},t.getCodecsOrExclude_=function(){var n=this,r={main:this.mainSegmentLoader_.getCurrentMediaInfo_()||{},audio:this.audioSegmentLoader_.getCurrentMediaInfo_()||{}};r.video=r.main;var e=Yu(this.master(),this.media()),a={},t=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(r.main.hasVideo&&(a.video=e.video||r.main.videoCodec||"avc1.4d400d"),r.main.isMuxed&&(a.video+=","+(e.audio||r.main.audioCodec||Cr)),(r.main.hasAudio&&!r.main.isMuxed||r.audio.hasAudio||t)&&(a.audio=e.audio||r.main.audioCodec||r.audio.audioCodec||Cr,r.audio.isFmp4=(r.main.hasAudio&&!r.main.isMuxed?r.main:r.audio).isFmp4),a.audio||a.video){var s,i,o={};if(["video","audio"].forEach(function(e){var t,i;a.hasOwnProperty(e)&&(t=r[e].isFmp4,i=a[e],!(t?gr:yr)(i))&&(i=r[e].isFmp4?"browser":"muxer",o[i]=o[i]||[],o[i].push(a[e]),"audio"===e&&(s=i))}),t&&s&&this.media().attributes.AUDIO&&(i=this.media().attributes.AUDIO,this.master().playlists.forEac
4720h(function(e){(e.attributes&&e.attributes.AUDIO)===i&&e!==n.media()&&(e.excludeUntil=1/0)}),this.logger_("excluding audio group "+i+" as "+s+' does not support codec(s): "'+a.audio+'"')),!Object.keys(o).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){var u=[];if(["video","audio"].forEach(function(e){var t=(pr(n.sourceUpdater_.codecs[e]||"")[0]||{}).type,i=(pr(a[e]||"")[0]||{}).type;t&&i&&t.toLowerCase()!==i.toLowerCase()&&u.push('"'+n.sourceUpdater_.codecs[e]+'" -> "'+a[e]+'"')}),u.length)return void this.blacklistCurrentPlaylist({playlist:this.media(),message:"Codec switching not supported: "+u.join(", ")+".",blacklistDuration:1/0,internal:!0})}return a}t=Object.keys(o).reduce(function(e,t){return e&&(e+=", "),e+=t+' does not support codec(s): "'+o[t].join(",")+'"'},"")+".";this.blacklistCurrentPlaylist({playlist:this.media(),internal:!0,message:t,blacklistDuration:1/0})}else this.blacklistCurrentPlaylist({playlist:this.media(),message:"Could not determine codecs for playlist.",blacklistDuration:1/0})},t.tryToCreateSourceBuffers_=function(){var e;"open"!==this.mediaSource.readyState||this.sourceUpdater_.hasCreatedSourceBuffers()||!this.areMediaTypesKnown_()||(e=this.getCodecsOrExclude_())&&(this.sourceUpdater_.createSourceBuffers(e),e=[e.video,e.audio].filter(Boolean).join(","),this.excludeIncompatibleVariants_(e))},t.excludeUnsupportedVariants_=function(){var n=this,r=this.master().playlists,a=[];Object.keys(r).forEach(function(e){var t,i=r[e];-1===a.indexOf(i.id)&&(a.push(i.id),t=[],!(e=Yu(n.master,i)).audio||yr(e.audio)||gr(e.audio)||t.push("audio codec "+e.audio),!e.video||yr(e.video)||gr(e.video)||t.push("video codec "+e.video),e.text&&"stpp.ttml.im1t"===e.text&&t.push("text codec "+e.text),t.length&&(i.excludeUntil=1/0,n.logger_("excluding "+i.id+" for unsupported: "+t.join(", "))))})},t.excludeIncompatibleVariants_=function(e){var r=this,a=[],s=this.master().playlists,e=Xu(pr(e)),o=Ku(e),u=e.video&&pr(e.video)[0]||null,l=e.audio&&pr(e.audio)[0]||null;Object.keys(s).forEach(function(e){var t,i,n=s[e];-1===a.indexOf(n.id)&&n.excludeUntil!==1/0&&(a.push(n.id),t=[],i=Yu(r.masterPlaylistLoader_.master,n),e=Ku(i),(i.audio||i.video)&&(e!==o&&t.push('codec count "'+e+'" !== "'+o+'"'),r.sourceUpdater_.canChangeType()||(e=i.video&&pr(i.video)[0]||null,i=i.audio&&pr(i.audio)[0]||null,e&&u&&e.type.toLowerCase()!==u.type.toLowerCase()&&t.push('video codec "'+e.type+'" !== "'+u.type+'"'),i&&l&&i.type.toLowerCase()!==l.type.toLowerCase()&&t.push('audio codec "'+i.type+'" !== "'+l.type+'"')),t.length&&(n.excludeUntil=1/0,r.logger_("blacklisting "+n.id+": "+t.join(" && ")))))})},t.updateAdCues_=function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){if(void 0===i&&(i=0),e.segments)for(var n=i,r=0;r<e.segments.length;r++){var a,s,o,u=e.segments[r];if(o=o||function(e,t){for(var i=e.cues,n=0;n<i.length;n++){var r=i[n];if(t>=r.adStartTime&&t<=r.adEndTime)return r}return null}(t,n+u.duration/2)){if("cueIn"in u){o.endTime=n,o.adEndTime=n,n+=u.duration,o=null;continue}if(n<o.endTime){n+=u.duration;continue}o.endTime+=u.duration}else"cueOut"in u&&((o=new window.VTTCue(n,n+u.duration,u.cueOut)).adStartTime=n,o.adEndTime=n+parseFloat(u.cueOut),t.addCue(o)),"cueOutCont"in u&&(a=(s=u.cueOutCont.split("/").map(parseFloat))[0],s=s[1],(o=new window.VTTCue(n,n+u.duration,"")).adStartTime=n-a,o.adEndTime=o.adStartTime+s,t.addCue(o));n+=u.duration}}(e,this.cueTagsTrack_,t)},t.goalBufferLength=function(){var e=this.tech_.currentTime(),t=Sl.GOAL_BUFFER_LENGTH,i=Sl.GOAL_BUFFER_LENGTH_RATE,n=Math.max(t,Sl.MAX_GOAL_BUFFER_LENGTH);return Math.min(t+e*i,n)},t.bufferLowWaterLine=function(){var e=this.tech_.currentTime(),t=Sl.BUFFER_LOW_WATER_LINE,i=Sl.BUFFER_LOW_WATER_LINE_RATE,n=Math.max(t,Sl.MAX_BUFFER_LOW_WATER_LINE),r=Math.max(t,Sl.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE);return Math.min(t+e*i,this.experimentalBufferBasedABR?r:n)},t.bufferHighWaterLine=function(){return Sl.BUFFER_HIGH_WATER_LINE},e}(tr.EventTarget),_c=["seeking","seeked","pause","playing","error"],bc=function(){function e(e){var i=this;this.masterPlaylistController_=e.masterPlaylistController,this.tech_=e.tech,this.seekable=e.seekable,this.allowSeeksWithinUnsafeLiveWindow=e.allowSeeksWithinUnsafeLiveWindow,this.liveRangeSafeTimeDelta=e.liveRangeSafeTimeDelta,this.media=e.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.timer_=null,this.checkCurrentTimeTimeout_=null,this.logger_=Oo("PlaybackWatcher"),this.logger_("initialize");function t(){return i.monitorCurrentTime_()}function n(){return i.monitorCurrentTime_()}function r(){return i.techWaiting_()}function a(){return i.cancelTimer_()}var s=this.masterPlaylistController_,o=["main","subtitle","audio"],u={};o.forEach(function(e){u[e]={reset:function(){return i.resetSegmentDownloads_(e)},updateend:function(){return i.checkSegmentDownloads_(e)}},s[e+"SegmentLoader_"].on("appendsdone",u[e].updateend),s[e+"SegmentLoader_"].on("playlistupdate",u[e].reset),i.tech_.on(["seeked","seeking"],u[e].reset)});function l(t){["main","audio"].forEach(function(e){s[e+"SegmentLoader_"][t]("appended",i.seekingAppendCheck_)})}this.seekingAppendCheck_=function(){i.fixesBadSeeks_()&&(i.consecutiveUpdates=0,i.lastRecordedTime=i.tech_.currentTime(),l("off"))},this.clearSeekingAppendCheck_=function(){return l("off")},this.watchForBadSeeking_=function(){i.clearSeekingAppendCheck_(),l("on")},this.tech_.on("seeked",this.clearSeekingAppendCheck_),this.tech_.on("seeking",this.watchForBadSeeking_),this.tech_.on("waiting",r),this.tech_.on(_c,a),this.tech_.on("canplay",n),this.tech_.one("play",t),this.dispose=function(){i.clearSeekingAppendCheck_(),i.logger_("dispose"),i.tech_.off("waiting",r),i.tech_.off(_c,a),i.tech_.off("canplay",n),i.tech_.off("play",t),i.tech_.off("seeking",i.watchForBadSeeking_),i.tech_.off("seeked",i.clearSeekingAppendCheck_),o.forEach(function(e){s[e+"SegmentLoader_"].off("appendsdone",u[e].updateend),s[e+"SegmentLoader_"].off("playlistupdate",u[e].reset),i.tech_.off(["seeked","seeking"],u[e].reset)}),i.checkCurrentTimeTimeout_&&window.clearTimeout(i.checkCurrentTimeTimeout_),i.cancelTimer_()}}var t=e.prototype;return t.monitorCurrentTime_=function(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&window.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=window.setTimeout(this.monitorCurrentTime_.bind(this),250)},t.resetSegmentDownloads_=function(e){var t=this.masterPlaylistController_[e+"SegmentLoader_"];0<this[e+"StalledDownloads_"]&&this.logger_("resetting possible stalled download count for "+e+" loader"),this[e+"StalledDownloads_"]=0,this[e+"Buffered_"]=t.buffered_()},t.checkSegmentDownloads_=function(e){var t=this.masterPlaylistController_,i=t[e+"SegmentLoader_"],n=i.buffered_(),r=function(e,t){if(e===t)return!1;if(!e&&t||!t&&e)return!0;
4720if(e.length!==t.length)return!0;for(var i=0;i<e.length;i++)if(e.start(i)!==t.start(i)||e.end(i)!==t.end(i))return!0;return!1}(this[e+"Buffered_"],n);this[e+"Buffered_"]=n,r?this.resetSegmentDownloads_(e):(this[e+"StalledDownloads_"]++,this.logger_("found #"+this[e+"StalledDownloads_"]+" "+e+" appends that did not increase buffer (possible stalled download)",{playlistId:i.playlist_&&i.playlist_.id,buffered:Bo(n)}),this[e+"StalledDownloads_"]<10||(this.logger_(e+" loader stalled download exclusion"),this.resetSegmentDownloads_(e),this.tech_.trigger({type:"usage",name:"vhs-"+e+"-download-exclusion"}),"subtitle"!==e&&t.blacklistCurrentPlaylist({message:"Excessive "+e+" segment downloading detected."},1/0)))},t.checkCurrentTime_=function(){if(!this.tech_.paused()&&!this.tech_.seeking()){var e=this.tech_.currentTime(),t=this.tech_.buffered();if(this.lastRecordedTime===e&&(!t.length||e+.1>=t.end(t.length-1)))return this.techWaiting_();5<=this.consecutiveUpdates&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e)}},t.cancelTimer_=function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null},t.fixesBadSeeks_=function(){if(!this.tech_.seeking())return!1;var e,t=this.seekable(),i=this.tech_.currentTime();if(this.afterSeekableWindow_(t,i,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(e=t.end(t.length-1)),"undefined"!=typeof(e=this.beforeSeekableWindow_(t,i)?(a=t.start(0))+(a===t.end(0)?0:.1):e))return this.logger_("Trying to seek outside of seekable at time "+i+" with seekable range "+Uo(t)+". Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0;for(var n=this.masterPlaylistController_.sourceUpdater_,r=this.tech_.buffered(),a=n.audioBuffer?n.audioBuffered():null,t=n.videoBuffer?n.videoBuffered():null,n=this.media(),s=n.partTargetDuration||2*(n.targetDuration-hl),o=[a,t],u=0;u<o.length;u++)if(o[u])if(jo(o[u],i)<s)return!1;r=No(r,i);return 0!==r.length&&(e=r.start(0)+.1,this.logger_("Buffered region starts ("+r.start(0)+") just beyond seek point ("+i+"). Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0)},t.waiting_=function(){var e,t;this.techWaiting_()||(e=this.tech_.currentTime(),t=this.tech_.buffered(),(t=Mo(t,e)).length&&e+3<=t.end(0)&&(this.cancelTimer_(),this.tech_.setCurrentTime(e),this.logger_("Stopped at "+e+" while inside a buffered region ["+t.start(0)+" -> "+t.end(0)+"]. Attempting to resume playback by seeking to the current time."),this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"}),this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})))},t.techWaiting_=function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()||null!==this.timer_)return!0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.tech_.setCurrentTime(i),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}e=this.tech_.vhs.masterPlaylistController_.sourceUpdater_,i=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:e.audioBuffered(),videoBuffered:e.videoBuffered(),currentTime:t}))return this.cancelTimer_(),this.tech_.setCurrentTime(t),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;e=No(i,t);if(0<e.length){i=e.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+i+", seeking to "+e.start(0)),this.cancelTimer_(),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*i,t),!0}return!1},t.afterSeekableWindow_=function(e,t,i,n){if(void 0===n&&(n=!1),!e.length)return!1;var r=e.end(e.length-1)+.1;return(r=!i.endList&&n?e.end(e.length-1)+3*i.targetDuration:r)<t},t.beforeSeekableWindow_=function(e,t){return!!(e.length&&0<e.start(0)&&t<e.start(0)-this.liveRangeSafeTimeDelta)},t.videoUnderflow_=function(e){var t,i,n=e.videoBuffered,r=e.audioBuffered,a=e.currentTime;
4720if(n)return n.length&&r.length?(i=Mo(n,a-3),e=Mo(n,a),(r=Mo(r,a)).length&&!e.length&&i.length&&(t={start:i.end(0),end:r.end(0)})):No(n,a).length||(t=this.gapFromVideoUnderflow_(n,a)),!!t&&(this.logger_("Encountered a gap in video from "+t.start+" to "+t.end+". Seeking to current time "+a),!0)},t.skipTheGap_=function(e){var t=this.tech_.buffered(),i=this.tech_.currentTime(),t=No(t,i);this.cancelTimer_(),0!==t.length&&i===e&&(this.logger_("skipTheGap_:","currentTime:",i,"scheduled currentTime:",e,"nextRange start:",t.start(0)),this.tech_.setCurrentTime(t.start(0)+hl),this.tech_.trigger({type:"usage",name:"vhs-gap-skip"}),this.tech_.trigger({type:"usage",name:"hls-gap-skip"}))},t.gapFromVideoUnderflow_=function(e,t){for(var i=function(e){if(e.length<2)return tr.createTimeRanges();for(var t=[],i=1;i<e.length;i++){var n=e.end(i-1),r=e.start(i);t.push([n,r])}return tr.createTimeRanges(t)}(e),n=0;n<i.length;n++){var r=i.start(n),a=i.end(n);if(t-r<4&&2<t-r)return{start:r,end:a}}return null},e}(),Tc={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},Sc={PlaylistLoader:yl,Playlist:fl,utils:zt,STANDARD_PLAYLIST_SELECTOR:ar,INITIAL_PLAYLIST_SELECTOR:function(){var t=this,e=this.playlists.master.playlists.filter(fl.isEnabled);return Ju(e,Zu),e.filter(function(e){return!!Yu(t.playlists.master,e).video})[0]||null},lastBandwidthSelector:ar,movingAverageBandwidthSelector:function(t){var i=-1,n=-1;if(t<0||1<t)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){var e=this.useDevicePixelRatio&&window.devicePixelRatio||1;return i<0&&(i=this.systemBandwidth,n=this.systemBandwidth),0<this.systemBandwidth&&this.systemBandwidth!==n&&(i=t*this.systemBandwidth+(1-t)*i,n=this.systemBandwidth),el(this.playlists.master,i,parseInt($u(this.tech_.el(),"width"),10)*e,parseInt($u(this.tech_.el(),"height"),10)*e,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)}},comparePlaylistBandwidth:Zu,comparePlaylistResolution:function(e,t){var i,n;return(i=(i=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width?e.attributes.RESOLUTION.width:i)||window.Number.MAX_VALUE)===(n=(n=t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width?t.attributes.RESOLUTION.width:n)||window.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:mu()};Object.keys(Sl).forEach(function(t){Object.defineProperty(Sc,t,{get:function(){return tr.log.warn("using Vhs."+t+" is UNSAFE be sure you know what you are doing"),Sl[t]},set:function(e){tr.log.warn("using Vhs."+t+" is UNSAFE be sure you know what you are doing"),"number"!=typeof e||e<0?tr.log.warn("value of Vhs."+t+" must be greater than or equal to 0"):Sl[t]=e}})});function wc(e,t){for(var i=t.media(),n=-1,r=0;r<e.length;r++)if(e[r].id===i.id){n=r;break}e.selectedIndex_=n,e.trigger({selectedIndex:n,type:"change"})}var Ec="videojs-vhs";Sc.canPlaySource=function(){return tr.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};function kc(e){var n=e.player,t=e.sourceKeySystems,i=e.audioMedia,e=e.mainPlaylists;if(!n.eme.initializeMediaKeys)return Promise.resolve();var r,e=(e=e=i?e.concat([i]):e,r=Object.keys(t),e.reduce(function(e,n){if(!n.contentProtection)return e;var t=r.reduce(function(e,t){var i=n.contentProtection[t];return i&&i.pssh&&(e[t]={pssh:i.pssh}),e},{});return Object.keys(t).length&&e.push(t),e},[])),a=[],s=[];return e.forEach(function(e){s.push(new Promise(function(e,t){n.tech_.one("keysessioncreated",e)})),a.push(new Promise(function(t,i){n.eme.initializeMediaKeys({keySystems:e},function(e){e?i(e):t()})}))}),Promise.race([Promise.all(a),Promise.race(s)])}function Cc(e){var t=e.player;return!!(e=function(e,t,i){if(!e)return e;var n={};t&&t.attributes&&t.attributes.CODECS&&(n=Xu(pr(t.attributes.CODECS))),i&&i.attributes&&i.attributes.CODECS&&(n.audio=i.attributes.CODECS);var r,a=mr(n.video),s=mr(n.audio),o={};for(r in e)o[r]={},s&&(o[r].audioContentType=s),a&&(o[r].videoContentType=a),t.contentProtection&&t.contentProtection[r]&&t.contentProtection[r].pssh&&(o[r].pssh=t.contentProtection[r].pssh),"string"==typeof e[r]&&(o[r].url=e[r]);return tr.mergeOptions(e,o)}(e.sourceKeySystems,e.media,e.audioMedia))&&(!((t.currentSource().keySystems=e)&&!t.eme)||(tr.log.warn("DRM encrypted source cannot be decrypted without a DRM plugin"),!1))}function Ic(){if(!window.localStorage)return null;var e=window.localStorage.getItem(Ec);if(!e)return null;try{return JSON.parse(e)}catch(e){return null}}Sc.supportsNativeHls=function(){if(!document||!document.createElement)return!1;var t=document.createElement("video");if(!tr.getTech("Html5").isSupported())return!1;return["application/vnd.apple.mpegurl","audio/mpegurl","audio/x-mpegurl","application/x-mpegurl","video/x-mpegurl","video/mpegurl","application/mpegurl"].some(function(e){return/maybe|probably/i.test(t.canPlayType(e))})}(),Sc.supportsNativeDash=!!(document&&document.createElement&&tr.getTech("Html5").isSupported())&&/maybe|probably/i.test(document.createElement("video").canPlayType("application/d
4720ash+xml")),Sc.supportsTypeNatively=function(e){return"hls"===e?Sc.supportsNativeHls:"dash"===e&&Sc.supportsNativeDash},Sc.isSupported=function(){return tr.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};var xc=function(r){function e(e,t,i){var n=r.call(this,t,tr.mergeOptions(i.hls,i.vhs))||this;if(i.hls&&Object.keys(i.hls).length&&tr.log.warn("Using hls options is deprecated. Use vhs instead."),"number"==typeof i.initialBandwidth&&(n.options_.bandwidth=i.initialBandwidth),n.logger_=Oo("VhsHandler"),t.options_&&t.options_.playerId&&((i=tr(t.options_.playerId)).hasOwnProperty("hls")||Object.defineProperty(i,"hls",{get:function(){return tr.log.warn("player.hls is deprecated. Use player.tech().vhs instead."),t.trigger({type:"usage",name:"hls-player-access"}),ft(n)},configurable:!0}),i.hasOwnProperty("vhs")||Object.defineProperty(i,"vhs",{get:function(){return tr.log.warn("player.vhs is deprecated. Use player.tech().vhs instead."),t.trigger({type:"usage",name:"vhs-player-access"}),ft(n)},configurable:!0}),i.hasOwnProperty("dash")||Object.defineProperty(i,"dash",{get:function(){return tr.log.warn("player.dash is deprecated. Use player.tech().vhs instead."),ft(n)},configurable:!0}),n.player_=i),n.tech_=t,n.source_=e,n.stats={},n.ignoreNextSeekingEvent_=!1,n.setOptions_(),n.options_.overrideNative&&t.overrideNativeAudioTracks&&t.overrideNativeVideoTracks)t.overrideNativeAudioTracks(!0),t.overrideNativeVideoTracks(!0);else if(n.options_.overrideNative&&(t.featuresNativeVideoTracks||t.featuresNativeAudioTracks))throw new Error("Overriding native HLS requires emulated tracks. See https://git.io/vMpjB");return n.on(document,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],function(e){var t=document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement;t&&t.contains(n.tech_.el())?n.masterPlaylistController_.fastQualityChange_():n.masterPlaylistController_.checkABR_()}),n.on(n.tech_,"seeking",function(){this.ignoreNextSeekingEvent_?this.ignoreNextSeekingEvent_=!1:this.setCurrentTime(this.tech_.currentTime())}),n.on(n.tech_,"error",function(){this.tech_.error()&&this.masterPlaylistController_&&this.masterPlaylistController_.pauseLoading()}),n.on(n.tech_,"play",n.play),n}mt(e,r);var t=e.prototype;return t.setOptions_=function(){var e,t=this;this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.handleManifestRedirects=!1!==this.options_.handleManifestRedirects,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.useDevicePixelRatio=this.options_.useDevicePixelRatio||!1,this.options_.smoothQualityChange=this.options_.smoothQualityChange||!1,this.options_.useBandwidthFromLocalStorage="undefined"!=typeof this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.useNetworkInformationApi=this.options_.useNetworkInformationApi||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,"number"!=typeof this.options_.blacklistDuration&&(this.options_.blacklistDuration=300),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage&&((e=Ic())&&e.bandwidth&&(this.options_.bandwidth=e.bandwidth,this.tech_.trigger({type:"usage",name:"vhs-bandwidth-from-local-storage"}),this.tech_.trigger({type:"usage",name:"hls-bandwidth-from-local-storage"})),e&&e.throughput&&(this.options_.throughput=e.throughput,this.tech_.trigger({type:"usage",name:"vhs-throughput-from-local-storage"}),this.tech_.trigger({type:"usage",name:"hls-throughput-from-local-storage"}))),"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=Sl.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===Sl.INITIAL_BANDWIDTH,["withCredentials","useDevicePixelRatio","limitRenditionByPlayerDimensions","bandwidth","smoothQualityChange","customTagParsers","customTagMappers","handleManifestRedirects","cacheEncryptionKeys","playlistSelector","initialPlaylistSelector","experimentalBufferBasedABR","liveRangeSafeTimeDelta","experimentalLLHLS","useNetworkInformationApi","experimentalExactManifestTimings","experimentalLeastPixelDiffSelector"].forEach(function(e){"undefined"!=typeof t.source_[e]&&(t.options_[e]=t.source_[e])}),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions,this.useDevicePixelRatio=this.options_.useDevicePixelRatio},t.src=function(e,t){var n=this;e&&(this.setOptions_(),this.options_.src=0===(e=this.source_.src).toLowerCase().indexOf("data:application/vnd.videojs.vhs+json,")?JSON.parse(e.substring(e.indexOf(",")+1)):e,this.options_.tech=this.tech_,this.options_.externVhs=Sc,this.options_.sourceType=vr(t),this.options_.seekTo=function(e){n.tech_.setCurrentTime(e)},this.options_.smoothQualityChange&&tr.log.warn("smoothQualityChange is deprecated and will be removed in the next major version"),this.masterPlaylistController_=new vc(this.options_),t=tr.mergeOptions({liveRangeSafeTimeDelta:.1},this.options_,{seekable:function(){return n.seekable()},media:function(){return n.masterPlaylistController_.media()},masterPlaylistController:this.masterPlaylistController_}),this.playbackWatcher_=new bc(t),this.masterPlaylistController_.on("error",function(){var e=tr.players[n.tech_.options_.playerId],t=n.masterPlaylistController_.error;"object"!=typeof t||t.code?"string"==typeof t&&(t={message:t,code:3}):t.code=3,e.error(t)}
4720),t=this.options_.experimentalBufferBasedABR?Sc.movingAverageBandwidthSelector(.55):Sc.STANDARD_PLAYLIST_SELECTOR,this.masterPlaylistController_.selectPlaylist=(this.selectPlaylist||t).bind(this),this.masterPlaylistController_.selectInitialPlaylist=Sc.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.masterPlaylistController_.masterPlaylistLoader_,this.mediaSource=this.masterPlaylistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get:function(){return this.masterPlaylistController_.selectPlaylist},set:function(e){this.masterPlaylistController_.selectPlaylist=e.bind(this)}},throughput:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.throughput.rate},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.throughput.rate=e,this.masterPlaylistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get:function(){var e=this.masterPlaylistController_.mainSegmentLoader_.bandwidth,t=window.navigator.connection||window.navigator.mozConnection||window.navigator.webkitConnection;return e=this.options_.useNetworkInformationApi&&t?1e7<=(t=1e3*t.downlink*1e3)&&1e7<=e?Math.max(e,t):t:e},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.bandwidth=e,this.masterPlaylistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get:function(){var e=1/(this.bandwidth||1),t=0<this.throughput?1/this.throughput:0;return Math.floor(1/(e+t))},set:function(){tr.log.error('The "systemBandwidth" property is read-only')}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return n.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return n.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return n.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return n.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return n.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return n.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return n.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return n.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},mediaAppends:{get:function(){return n.masterPlaylistController_.mediaAppends_()||0},enumerable:!0},mainAppendsToLoadedData:{get:function(){return n.masterPlaylistController_.mainAppendsToLoadedData_()||0},enumerable:!0},audioAppendsToLoadedData:{get:function(){return n.masterPlaylistController_.audioAppendsToLoadedData_()||0},enumerable:!0},appendsToLoadedData:{get:function(){return n.masterPlaylistController_.appendsToLoadedData_()||0},enumerable:!0},timeToLoadedData:{get:function(){return n.masterPlaylistController_.timeToLoadedData_()||0},enumerable:!0},buffered:{get:function(){return Bo(n.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return n.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return n.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return n.tech_.name_},enumerable:!0},duration:{get:function(){return n.tech_.duration()},enumerable:!0},master:{get:function(){return n.playlists.master},enumerable:!0},playerDimensions:{get:function(){return n.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return Bo(n.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return n.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",function(){n.options_.useBandwidthFromLocalStorage&&function(e){if(!window.localStorage)return;var t=(t=Ic())?tr.mergeOptions(t,e):e;try{window.localStorage.setItem(Ec,JSON.stringify(t))}catch(e){return}}({bandwidth:n.bandwidth,throughput:Math.round(n.throughput)})}),this.masterPlaylistController_.on("selectedinitialmedia",function(){var i;(i=n).representations=function(){var e=i.masterPlaylistController_.master(),e=nu(e)?i.masterPlaylistController_.getAudioTrackPlaylists_():e.playlists;return e?e.filter(function(e){return!$o(e)}
4720).map(function(e,t){return new zl(i,e,e.id)}):[]}}),this.masterPlaylistController_.sourceUpdater_.on("createdsourcebuffers",function(){n.setupEme_()}),this.on(this.masterPlaylistController_,"progress",function(){this.tech_.trigger("progress")}),this.on(this.masterPlaylistController_,"firstplay",function(){this.ignoreNextSeekingEvent_=!0}),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=window.URL.createObjectURL(this.masterPlaylistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_)))},t.createKeySessions_=function(){var t=this,e=this.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader;this.logger_("waiting for EME key session creation"),kc({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:e&&e.media(),mainPlaylists:this.playlists.master.playlists}).then(function(){t.logger_("created EME key session"),t.masterPlaylistController_.sourceUpdater_.initializedEme()}).catch(function(e){t.logger_("error while creating EME key session",e),t.player_.error({message:"Failed to initialize media keys for EME",code:3})})},t.handleWaitingForKey_=function(){this.logger_("waitingforkey fired, attempting to create any new key sessions"),this.createKeySessions_()},t.setupEme_=function(){var t=this,e=this.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader,e=Cc({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:e&&e.media()});this.player_.tech_.on("keystatuschange",function(e){"output-restricted"===e.status&&t.masterPlaylistController_.blacklistCurrentPlaylist({playlist:t.masterPlaylistController_.media(),message:"DRM keystatus changed to "+e.status+". Playlist will fail to play. Check for HDCP content.",blacklistDuration:1/0})}),this.handleWaitingForKey_=this.handleWaitingForKey_.bind(this),this.player_.tech_.on("waitingforkey",this.handleWaitingForKey_),11!==tr.browser.IE_VERSION&&e?this.createKeySessions_():this.masterPlaylistController_.sourceUpdater_.initializedEme()},t.setupQualityLevels_=function(){var i=this,e=tr.players[this.tech_.options_.playerId];
4720e&&e.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=e.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",function(){var t,e;t=i.qualityLevels_,(e=i).representations().forEach(function(e){t.addQualityLevel(e)}),wc(t,e.playlists)}),this.playlists.on("mediachange",function(){wc(i.qualityLevels_,i.playlists)}))},e.version=function(){return{"@videojs/http-streaming":"2.13.1","mux.js":"6.0.1","mpd-parser":"0.21.0","m3u8-parser":"4.7.0","aes-decrypter":"3.1.2"}},t.version=function(){return this.constructor.version()},t.canChangeType=function(){return sc.canChangeType()},t.play=function(){this.masterPlaylistController_.play()},t.setCurrentTime=function(e){this.masterPlaylistController_.setCurrentTime(e)},t.duration=function(){return this.masterPlaylistController_.duration()},t.seekable=function(){return this.masterPlaylistController_.seekable()},t.dispose=function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.tech_&&delete this.tech_.hls,this.mediaSourceUrl_&&window.URL.revokeObjectURL&&(window.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),this.tech_&&this.tech_.off("waitingforkey",this.handleWaitingForKey_),r.prototype.dispose.call(this)},t.convertToProgramTime=function(e,t){return wu({playlist:this.masterPlaylistController_.media(),time:e,callback:t})},t.seekToProgramTime=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=2),Eu({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:n,pauseAfterSeek:i,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})},e}(tr.getComponent("Component")),Ac={name:"videojs-http-streaming",VERSION:"2.13.1",canHandleSource:function(e,t){t=tr.mergeOptions(tr.options,t=void 0===t?{}:t);return Ac.canPlayType(e.type,t)},handleSource:function(e,t,i){i=tr.mergeOptions(tr.options,i=void 0===i?{}:i);return t.vhs=new xc(e,t,i),tr.hasOwnProperty("hls")||Object.defineProperty(t,"hls",{get:function(){return tr.log.warn("player.tech().hls is deprecated. Use player.tech().vhs instead."),t.vhs},configurable:!0}),t.vhs.xhr=mu(),t.vhs.src(e.src,e.type),t.vhs},canPlayType:function(e,t){var i=tr.mergeOptions(tr.options,t=void 0===t?{}:t),t=i.vhs,t=(t=void 0===t?{}:t).overrideNative,t=void 0===t?!tr.browser.IS_ANY_SAFARI:t,i=i.hls,i=(i=void 0===i?{}:i).overrideNative,i=void 0!==i&&i,e=vr(e);return e&&(!Sc.supportsTypeNatively(e)||i||t)?"maybe":""}};return gr("avc1.4d400d,mp4a.40.2")&&tr.getTech("Html5").registerSourceHandler(Ac,0),tr.VhsHandler=xc,Object.defineProperty(tr,"HlsHandler",{get:function(){return tr.log.warn("videojs.HlsHandler is deprecated. Use videojs.VhsHandler instead."),xc},configurable:!0}),tr.VhsSourceHandler=Ac,Object.defineProperty(tr,"HlsSourceHandler",{get:function(){return tr.log.warn("videojs.HlsSourceHandler is deprecated. Use videojs.VhsSourceHandler instead."),Ac},configurable:!0}),tr.Vhs=Sc,Object.defineProperty(tr,"Hls",{get:function(){return tr.log.warn("videojs.Hls is deprecated. Use videojs.Vhs instead."),Sc},configurable:!0}),tr.use||(tr.registerComponent("Hls",Sc),tr.registerComponent("Vhs",Sc)),tr.options.vhs=tr.options.vhs||{},tr.options.hls=tr.options.hls||{},tr.getPlugin&&tr.getPlugin("reloadSourceOnError")||(tr.registerPlugin||tr.plugin)("reloadSourceOnError",function(e){Xl(this,e)}),tr}); 4721 !function(){!function(a){var b=a&&a.videojs;b&&(b.CDN_VERSION="7.18.1")}(window)}(); 4722// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/admin/lib/videojs-vr/videojs-vr.js?ver=1 4723/*! @name videojs-vr @version 1.7.2 @license Apache-2.0 */ 4724(function (global, factory) { 4725 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('global/window'), require('global/document'), require('video.js')) : 4726 typeof define === 'function' && define.amd ? define(['global/window', 'global/document', 'video.js'], factory) : 4727 (global = global || self, global.videojsVr = factory(global.window, global.document, global.videojs)); 4728 }(this, (function (window$1, document$1, videojs) { 'use strict'; 4729 4730 window$1 = window$1 && window$1.hasOwnProperty('default') ? window$1['default'] : window$1; 4731 document$1 = document$1 && document$1.hasOwnProperty('default') ? document$1['default'] : document$1; 4732 videojs = videojs && videojs.hasOwnProperty('default') ? videojs['default'] : videojs; 4733 4734 function _assertThisInitialized(self) { 4735 if (self === void 0) { 4736 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 4737 } 4738 4739 return self; 4740 } 4741 4742 var assertThisInitialized = _assertThisInitialized; 4743 4744 function _inheritsLoose(subClass, superClass) { 4745 subClass.prototype = Object.create(superClass.prototype); 4746 subClass.prototype.constructor = subClass; 4747 subClass.__proto__ = superClass; 4748 } 4749 4750 var inheritsLoose = _inheritsLoose; 4751 4752 var version = "1.7.2"; 4753
4754 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 4755 4756 function unwrapExports (x) { 4757 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 4758 } 4759 4760 function createCommonjsModule(fn, module) { 4761 return module = { exports: {} }, fn(module, module.exports), module.exports; 4762 } 4763 4764 var webvrPolyfill = createCommonjsModule(function (module, exports) { 4765 /** 4766 * @license 4767 * webvr-polyfill 4768 * Copyright (c) 2015-2017 Google 4769 * Licensed under the Apache License, Version 2.0 (the "License"); 4770 * you may not use this file except in compliance with the License. 4771 * You may obtain a copy of the License at 4772 * 4773 * http://www.apache.org/licenses/LICENSE-2.0 4774 * 4775 * Unless required by applicable law or agreed to in writing, software 4776 * distributed under the License is distributed on an "AS IS" BASIS, 4777 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4778 * See the License for the specific language governing permissions and 4779 * limitations under the License. 4780 */ 4781 4782 /** 4783 * @license 4784 * cardboard-vr-display 4785 * Copyright (c) 2015-2017 Google 4786 * Licensed under the Apache License, Version 2.0 (the "License"); 4787 * you may not use this file except in compliance with the License. 4788 * You may obtain a copy of the License at 4789 * 4790 * http://www.apache.org/licenses/LICENSE-2.0 4791 * 4792 * Unless required by applicable law or agreed to in writing, software 4793 * distributed under the License is distributed on an "AS IS" BASIS, 4794 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4795 * See the License for the specific language governing permissions and 4796 * limitations under the License. 4797 */ 4798 4799 /** 4800 * @license 4801 * webvr-polyfill-dpdb 4802 * Copyright (c) 2017 Google 4803 * Licensed under the Apache License, Version 2.0 (the "License"); 4804 * you may not use this file except in compliance with the License. 4805 * You may obtain a copy of the License at 4806 * 4807 * http://www.apache.org/licenses/LICENSE-2.0 4808 * 4809 * Unless required by applicable law or agreed to in writing, software 4810 * distributed under the License is distributed on an "AS IS" BASIS, 4811 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4812 * See the License for the specific language governing permissions and 4813 * limitations under the License. 4814 */ 4815 4816 /** 4817 * @license 4818 * wglu-preserve-state 4819 * Copyright (c) 2016, Brandon Jones. 4820 * 4821 * Permission is hereby granted, free of charge, to any person obtaining a copy 4822 * of this software and associated documentation files (the "Software"), to deal 4823 * in the Software without restriction, including without limitation the rights 4824 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 4825 * copies of the Software, and to permit persons to whom the Software is 4826 * furnished to do so, subject to the following conditions: 4827 * 4828 * The above copyright notice and this permission notice shall be included in 4829 * all copies or substantial portions of the Software. 4830 * 4831 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4832 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4833 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4834 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4835 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4836 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 4837 * THE SOFTWARE. 4838 */ 4839 4840 /** 4841 * @license 4842 * nosleep.js 4843 * Copyright (c) 2017, Rich Tibbett 4844 * 4845 * Permission is hereby granted, free of charge, to any person obtaining a copy 4846 * of this software and associated documentation files (the "Software"), to deal 4847 * in the Software without restriction, including without limitation the rights 4848 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 4849 * copies of the Software, and to permit persons to whom the Software is 4850 * furnished to do so, subject to the following conditions: 4851 * 4852 * The above copyright notice and this permission notice shall be included in 4853 * all copies or substantial portions of the Software. 4854 * 4855 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4856 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4857 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4858 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4859 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4860 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 4861 * THE SOFTWARE. 4862 */ 4863 4864 (function (global, factory) { 4865 module.exports = factory() ; 4866 }(commonjsGlobal, (function () { 4867 var commonjsGlobal$1 = typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof self !== 'undefined' ? self : {}; 4868 4869 4870 4871 function unwrapExports (x) { 4872 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 4873 } 4874 4875 function createCommonjsModule(fn, module) { 4876 return module = { exports: {} }, fn(module, module.exports), module.exports; 4877 } 4878 4879 var race = function race(promises) { 4880 if (Promise.race) { 4881 return Promise.race(promises); 4882 } 4883 return new Promise(function (resolve, reject) { 4884 for (var i = 0; i < promises.length; i++) { 4885 promises[i].then(resolve, reject); 4886 } 4887 }); 4888 }; 4889 4890 var isMobile = function isMobile() { 4891 return (/Android/i.test(navigator.userAgent) || /iPhone|iPad|iPod/i.test(navigator.userAgent) 4892 ); 4893 }; 4894 var copyArray = function copyArray(source, dest) { 4895 for (var i = 0, n = source.length; i < n; i++) { 4896 dest[i] = source[i]; 4897 } 4898 }; 4899 var extend = function extend(dest, src) { 4900 for (var key in src) { 4901 if (src.hasOwnProperty(key)) { 4902 dest[key] = src[key]; 4903 } 4904 } 4905 return dest; 4906 }; 4907 4908 var cardboardVrDisplay = createCommonjsModule(function (module, exports
4908) { 4909 /** 4910 * @license 4911 * cardboard-vr-display 4912 * Copyright (c) 2015-2017 Google 4913 * Licensed under the Apache License, Version 2.0 (the "License"); 4914 * you may not use this file except in compliance with the License. 4915 * You may obtain a copy of the License at 4916 * 4917 * http://www.apache.org/licenses/LICENSE-2.0 4918 * 4919 * Unless required by applicable law or agreed to in writing, software 4920 * distributed under the License is distributed on an "AS IS" BASIS, 4921 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4922 * See the License for the specific language governing permissions and 4923 * limitations under the License. 4924 */ 4925 /** 4926 * @license 4927 * gl-preserve-state 4928 * Copyright (c) 2016, Brandon Jones. 4929 * 4930 * Permission is hereby granted, free of charge, to any person obtaining a copy 4931 * of this software and associated documentation files (the "Software"), to deal 4932 * in the Software without restriction, including without limitation the rights 4933 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 4934 * copies of the Software, and to permit persons to whom the Software is 4935 * furnished to do so, subject to the following conditions: 4936 * 4937 * The above copyright notice and this permission notice shall be included in 4938 * all copies or substantial portions of the Software. 4939 * 4940 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4941 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4942 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4943 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4944 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4945 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 4946 * THE SOFTWARE. 4947 */ 4948 /** 4949 * @license 4950 * webvr-polyfill-dpdb 4951 * Copyright (c) 2015-2017 Google 4952 * Licensed under the Apache License, Version 2.0 (the "License"); 4953 * you may not use this file except in compliance with the License. 4954 * You may obtain a copy of the License at 4955 * 4956 * http://www.apache.org/licenses/LICENSE-2.0 4957 * 4958 * Unless required by applicable law or agreed to in writing, software 4959 * distributed under the License is distributed on an "AS IS" BASIS, 4960 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4961 * See the License for the specific language governing permissions and 4962 * limitations under the License. 4963 */ 4964 /** 4965 * @license 4966 * nosleep.js 4967 * Copyright (c) 2017, Rich Tibbett 4968 * 4969 * Permission is hereby granted, free of charge, to any person obtaining a copy 4970 * of this software and associated documentation files (the "Software"), to deal 4971 * in the Software without restriction, including without limitation the rights 4972 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 4973 * copies of the Software, and to permit persons to whom the Software is 4974 * furnished to do so, subject to the following conditions: 4975 * 4976 * The above copyright notice and this permission notice shall be included in 4977 * all copies or substantial portions of the Software. 4978 * 4979 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4980 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4981 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4982 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4983 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4984 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 4985 * THE SOFTWARE. 4986 */ 4987 (function (global, factory) { 4988 module.exports = factory(); 4989 }(commonjsGlobal$1, (function () { var classCallCheck = function (instance, Constructor) { 4990 if (!(instance instanceof Constructor)) { 4991 throw new TypeError("Cannot call a class as a function"); 4992 } 4993 }; 4994 var createClass = function () { 4995 function defineProperties(target, props) { 4996 for (var i = 0; i < props.length; i++) { 4997 var descriptor = props[i]; 4998 descriptor.enumerable = descriptor.enumerable || false; 4999 descriptor.configurable = true; 5000 if ("value" in descriptor) descriptor.writable = true;
vendor: 26,977 bytes, lines 5001-5755
5001 Object.defineProperty(target, descriptor.key, descriptor); 5002 } 5003 } 5004 return function (Constructor, protoProps, staticProps) { 5005 if (protoProps) defineProperties(Constructor.prototype, protoProps); 5006 if (staticProps) defineProperties(Constructor, staticProps); 5007 return Constructor; 5008 }; 5009 }(); 5010 var slicedToArray = function () { 5011 function sliceIterator(arr, i) { 5012 var _arr = []; 5013 var _n = true; 5014 var _d = false; 5015 var _e = undefined; 5016 try { 5017 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 5018 _arr.push(_s.value); 5019 if (i && _arr.length === i) break; 5020 } 5021 } catch (err) { 5022 _d = true; 5023 _e = err; 5024 } finally { 5025 try { 5026 if (!_n && _i["return"]) _i["return"](); 5027 } finally { 5028 if (_d) throw _e; 5029 } 5030 } 5031 return _arr; 5032 } 5033 return function (arr, i) { 5034 if (Array.isArray(arr)) { 5035 return arr; 5036 } else if (Symbol.iterator in Object(arr)) { 5037 return sliceIterator(arr, i); 5038 } else { 5039 throw new TypeError("Invalid attempt to destructure non-iterable instance"); 5040 } 5041 }; 5042 }(); 5043 var MIN_TIMESTEP = 0.001; 5044 var MAX_TIMESTEP = 1; 5045 var base64 = function base64(mimeType, _base) { 5046 return 'data:' + mimeType + ';base64,' + _base; 5047 }; 5048 var lerp = function lerp(a, b, t) { 5049 return a + (b - a) * t; 5050 }; 5051 var isIOS = function () { 5052 var isIOS = /iPad|iPhone|iPod/.test(navigator.platform); 5053 return function () { 5054 return isIOS; 5055 }; 5056 }(); 5057 var isWebViewAndroid = function () { 5058 var isWebViewAndroid = navigator.userAgent.indexOf('Version') !== -1 && navigator.userAgent.indexOf('Android') !== -1 && navigator.userAgent.indexOf('Chrome') !== -1; 5059 return function () { 5060 return isWebViewAndroid; 5061 }; 5062 }(); 5063 var isSafari = function () { 5064 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 5065 return function () { 5066 return isSafari; 5067 }; 5068 }(); 5069 var isFirefoxAndroid = function () { 5070 var isFirefoxAndroid = navigator.userAgent.indexOf('Firefox') !== -1 && navigator.userAgent.indexOf('Android') !== -1; 5071 return function () { 5072 return isFirefoxAndroid; 5073 }; 5074 }(); 5075 var getChromeVersion = function () { 5076 var match = navigator.userAgent.match(/.*Chrome\/([0-9]+)/); 5077 var value = match ? parseInt(match[1], 10) : null; 5078 return function () { 5079 return value; 5080 }; 5081 }(); 5082 var isChromeWithoutDeviceMotion = function () { 5083 var value = false; 5084 if (getChromeVersion() === 65) { 5085 var match = navigator.userAgent.match(/.*Chrome\/([0-9\.]*)/); 5086 if (match) { 5087 var _match$1$split = match[1].split('.'), 5088 _match$1$split2 = slicedToArray(_match$1$split, 4), 5089 major = _match$1$split2[0], 5090 minor = _match$1$split2[1], 5091 branch = _match$1$split2[2], 5092 build = _match$1$split2[3]; 5093 value = parseInt(branch, 10) === 3325 && parseInt(build, 10) < 148; 5094 } 5095 } 5096 return function () { 5097 return value; 5098 }; 5099 }(); 5100 var isR7 = function () { 5101 var isR7 = navigator.userAgent.indexOf('R7 Build') !== -1; 5102 return function () { 5103 return isR7; 5104 }; 5105 }(); 5106 var isLandscapeMode = function isLandscapeMode() { 5107 var rtn = window.orientation == 90 || window.orientation == -90; 5108 return isR7() ? !rtn : rtn; 5109 }; 5110 var isTimestampDeltaValid = function isTimestampDeltaValid(timestampDeltaS) { 5111 if (isNaN(timestampDeltaS)) { 5112 return false; 5113 } 5114 if (timestampDeltaS <= MIN_TIMESTEP) { 5115 return false; 5116 } 5117 if (timestampDeltaS > MAX_TIMESTEP) { 5118 return false; 5119 } 5120 return true; 5121 }; 5122 var getScreenWidth = function getScreenWidth() { 5123 return Math.max(window.screen.width, window.screen.height) * window.devicePixelRatio; 5124 }; 5125 var getScreenHeight = function getScreenHeight() { 5126 return Math.min(window.screen.width, window.screen.height) * window.devicePixelRatio; 5127 }; 5128 var requestFullscreen = function requestFullscreen(element) { 5129 if (isWebViewAndroid()) { 5130 return false; 5131 } 5132 if (element.requestFullscreen) { 5133 element.requestFullscreen(); 5134 } else if (element.webkitRequestFullscreen) { 5135 element.webkitRequestFullscreen(); 5136 } else if (element.mozRequestFullScreen) { 5137 element.mozRequestFullScreen(); 5138 } else if (element.msRequestFullscreen) { 5139 element.msRequestFullscreen(); 5140 } else { 5141 return false; 5142 } 5143 return true; 5144 }; 5145 var exitFullscreen = function exitFullscreen() { 5146 if (document.exitFullscreen) { 5147 document.exitFullscreen(); 5148 } else if (document.webkitExitFullscreen) { 5149 document.webkitExitFullscreen(); 5150 } else if (document.mozCancelFullScreen) { 5151 document.mozCancelFullScreen(); 5152 } else if (document.msExitFullscreen) { 5153 document.msExitFullscreen(); 5154 } else { 5155 return false; 5156 } 5157 return true; 5158 }; 5159 var getFullscreenElement = function getFullscreenElement() { 5160 return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement; 5161 }; 5162 var linkProgram = function linkProgram(gl, vertexSource, fragmentSource, attribLocationMap) { 5163 var vertexShader = gl.createShader(gl.VERTEX_SHADER); 5164 gl.shaderSource(vertexShader, vertexSource); 5165 gl.compileShader(vertexShader); 5166 var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); 5167 gl.shaderSource(fragmentShader, fragmentSource); 5168 gl.compileShader(fragmentShader); 5169 var program = gl.createProgram(); 5170 gl.attachShader(program, vertexShader); 5171 gl.attachShader(program, fragmentShader); 5172 for (var attribName in attribLocationMap) { 5173 gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); 5174 }gl.linkProgram(program); 5175 gl.deleteShader(vertexShader); 5176 gl.deleteShader(fragmentShader); 5177 return program; 5178 }; 5179 var getProgramUniforms = function getProgramUniforms(gl, program) { 5180 var uniforms = {}; 5181 var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 5182 var uniformName = ''; 5183 for (var i = 0; i < uniformCount; i++) { 5184 var uniformInfo = gl.getActiveUniform(program, i); 5185 uniformName = uniformInfo.name.replace('[0]', ''); 5186 uniforms[uniformName] = gl.getUniformLocation(program, uniformName); 5187 } 5188 return uniforms; 5189 }; 5190 var orthoMatrix = function orthoMatrix(out, left, right, bottom, top, near, far) { 5191 var lr = 1 / (left - right), 5192 bt = 1 / (bottom - top), 5193 nf = 1 / (near - far); 5194 out[0] = -2 * lr; 5195 out[1] = 0; 5196 out[2] = 0; 5197 out[3] = 0; 5198 out[4] = 0; 5199 out[5] = -2 * bt; 5200 out[6] = 0; 5201 out[7] = 0; 5202 out[8] = 0; 5203 out[9] = 0; 5204 out[10] = 2 * nf; 5205 out[11] = 0; 5206 out[12] = (left + right) * lr; 5207 out[13] = (top + bottom) * bt; 5208 out[14] = (far + near) * nf; 5209 out[15] = 1; 5210 return out; 5211 }; 5212 var isMobile = function isMobile() { 5213 var check = false; 5214 (function (a) { 5215 if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; 5216 })(navigator.userAgent || navigator.vendor || window.opera); 5217 return check; 5218 }; 5219 var extend = function extend(dest, src) { 5220 for (var key in src) { 5221 if (src.hasOwnProperty(key)) { 5222 dest[key] = src[key]; 5223 } 5224 } 5225 return dest; 5226 }; 5227 var safariCssSizeWorkaround = function safariCssSizeWorkaround(canvas) { 5228 if (isIOS()) { 5229 var width = canvas.style.width; 5230 var height = canvas.style.height; 5231 canvas.style.width = parseInt(width) + 1 + 'px'; 5232 canvas.style.height = parseInt(height) + 'px'; 5233 setTimeout(function () { 5234 canvas.style.width = width; 5235 canvas.style.height = height; 5236 }, 100); 5237 } 5238 window.canvas = canvas; 5239 }; 5240 var frameDataFromPose = function () { 5241 var piOver180 = Math.PI / 180.0; 5242 var rad45 = Math.PI * 0.25; 5243 function mat4_perspectiveFromFieldOfView(out, fov, near, far) { 5244 var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45), 5245 downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45), 5246 leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45), 5247 rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45), 5248 xScale = 2.0 / (leftTan + rightTan), 5249 yScale = 2.0 / (upTan + downTan); 5250 out[0] = xScale; 5251 out[1] = 0.0; 5252 out[2] = 0.0; 5253 out[3] = 0.0; 5254 out[4] = 0.0; 5255 out[5] = yScale; 5256 out[6] = 0.0; 5257 out[7] = 0.0; 5258 out[8] = -((leftTan - rightTan) * xScale * 0.5); 5259 out[9] = (upTan - downTan) * yScale * 0.5; 5260 out[10] = far / (near - far); 5261 out[11] = -1.0; 5262 out[12] = 0.0; 5263 out[13] = 0.0; 5264 out[14] = far * near / (near - far); 5265 out[15] = 0.0; 5266 return out; 5267 } 5268 function mat4_fromRotationTranslation(out, q, v) { 5269 var x = q[0], 5270 y = q[1], 5271 z = q[2], 5272 w = q[3], 5273 x2 = x + x, 5274 y2 = y + y, 5275 z2 = z + z, 5276 xx = x * x2, 5277 xy = x * y2, 5278 xz = x * z2, 5279 yy = y * y2, 5280 yz = y * z2, 5281 zz = z * z2, 5282 wx = w * x2, 5283 wy = w * y2, 5284 wz = w * z2; 5285 out[0] = 1 - (yy + zz); 5286 out[1] = xy + wz; 5287 out[2] = xz - wy; 5288 out[3] = 0; 5289 out[4] = xy - wz; 5290 out[5] = 1 - (xx + zz); 5291 out[6] = yz + wx; 5292 out[7] = 0; 5293 out[8] = xz + wy; 5294 out[9] = yz - wx; 5295 out[10] = 1 - (xx + yy); 5296 out[11] = 0; 5297 out[12] = v[0]; 5298 out[13] = v[1]; 5299 out[14] = v[2]; 5300 out[15] = 1; 5301 return out; 5302 } 5303 function mat4_translate(out, a, v) { 5304 var x = v[0], 5305 y = v[1], 5306 z = v[2], 5307 a00, 5308 a01, 5309 a02, 5310 a03, 5311 a10, 5312 a11, 5313 a12, 5314 a13, 5315 a20, 5316 a21, 5317 a22, 5318 a23; 5319 if (a === out) { 5320 out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; 5321 out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; 5322 out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; 5323 out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; 5324 } else { 5325 a00 = a[0];a01 = a[1];a02 = a[2];a03 = a[3]; 5326 a10 = a[4];a11 = a[5];a12 = a[6];a13 = a[7]; 5327 a20 = a[8];a21 = a[9];a22 = a[10];a23 = a[11]; 5328 out[0] = a00;out[1] = a01;out[2] = a02;out[3] = a03; 5329 out[4] = a10;out[5] = a11;out[6] = a12;out[7] = a13; 5330 out[8] = a20;out[9] = a21;out[10] = a22;out[11] = a23; 5331 out[12] = a00 * x + a10 * y + a20 * z + a[12]; 5332 out[13] = a01 * x + a11 * y + a21 * z + a[13]; 5333 out[14] = a02 * x + a12 * y + a22 * z + a[14]; 5334 out[15] = a03 * x + a13 * y + a23 * z + a[15]; 5335 } 5336 return out; 5337 } 5338 function mat4_invert(out, a) { 5339 var a00 = a[0], 5340 a01 = a[1], 5341 a02 = a[2], 5342 a03 = a[3], 5343 a10 = a[4], 5344 a11 = a[5], 5345 a12 = a[6], 5346 a13 = a[7], 5347 a20 = a[8], 5348 a21 = a[9], 5349 a22 = a[10], 5350 a23 = a[11], 5351 a30 = a[12], 5352 a31 = a[13], 5353 a32 = a[14], 5354 a33 = a[15], 5355 b00 = a00 * a11 - a01 * a10, 5356 b01 = a00 * a12 - a02 * a10, 5357 b02 = a00 * a13 - a03 * a10, 5358 b03 = a01 * a12 - a02 * a11, 5359 b04 = a01 * a13 - a03 * a11, 5360 b05 = a02 * a13 - a03 * a12, 5361 b06 = a20 * a31 - a21 * a30, 5362 b07 = a20 * a32 - a22 * a30, 5363 b08 = a20 * a33 - a23 * a30, 5364 b09 = a21 * a32 - a22 * a31, 5365 b10 = a21 * a33 - a23 * a31, 5366 b11 = a22 * a33 - a23 * a32, 5367 det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 5368 if (!det) { 5369 return null; 5370 } 5371 det = 1.0 / det; 5372 out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; 5373 out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; 5374 out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; 5375 out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; 5376 out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; 5377 out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; 5378 out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; 5379 out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; 5380 out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; 5381 out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; 5382 out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; 5383 out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; 5384 out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; 5385 out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; 5386 out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; 5387 out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; 5388 return out; 5389 } 5390 var defaultOrientation = new Float32Array([0, 0, 0, 1]); 5391 var defaultPosition = new Float32Array([0, 0, 0]); 5392 function updateEyeMatrices(projection, view, pose, fov, offset, vrDisplay) { 5393 mat4_perspectiveFromFieldOfView(projection, fov || null, vrDisplay.depthNear, vrDisplay.depthFar); 5394 var orientation = pose.orientation || defaultOrientation; 5395 var position = pose.position || defaultPosition; 5396 mat4_fromRotationTranslation(view, orientation, position); 5397 if (offset) mat4_translate(view, view, offset); 5398 mat4_invert(view, view); 5399 } 5400 return function (frameData, pose, vrDisplay) { 5401 if (!frameData || !pose) return false; 5402 frameData.pose = pose; 5403 frameData.timestamp = pose.timestamp; 5404 updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay._getFieldOfView("left"), vrDisplay._getEyeOffset("left"), vrDisplay); 5405 updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay._getFieldOfView("right"), vrDisplay._getEyeOffset("right"), vrDisplay); 5406 return true; 5407 }; 5408 }(); 5409 var isInsideCrossOriginIFrame = function isInsideCrossOriginIFrame() { 5410 var isFramed = window.self !== window.top; 5411 var refOrigin = getOriginFromUrl(document.referrer); 5412 var thisOrigin = getOriginFromUrl(window.location.href); 5413 return isFramed && refOrigin !== thisOrigin; 5414 }; 5415 var getOriginFromUrl = function getOriginFromUrl(url) { 5416 var domainIdx; 5417 var protoSepIdx = url.indexOf("://"); 5418 if (protoSepIdx !== -1) { 5419 domainIdx = protoSepIdx + 3; 5420 } else { 5421 domainIdx = 0; 5422 } 5423 var domainEndIdx = url.indexOf('/', domainIdx); 5424 if (domainEndIdx === -1) { 5425 domainEndIdx = url.length; 5426 } 5427 return url.substring(0, domainEndIdx); 5428 }; 5429 var getQuaternionAngle = function getQuaternionAngle(quat) { 5430 if (quat.w > 1) { 5431 console.warn('getQuaternionAngle: w > 1'); 5432 return 0; 5433 } 5434 var angle = 2 * Math.acos(quat.w); 5435 return angle; 5436 }; 5437 var warnOnce = function () { 5438 var observedWarnings = {}; 5439 return function (key, message) { 5440 if (observedWarnings[key] === undefined) { 5441 console.warn('webvr-polyfill: ' + message); 5442 observedWarnings[key] = true; 5443 } 5444 }; 5445 }(); 5446 var deprecateWarning = function deprecateWarning(deprecated, suggested) { 5447 var alternative = suggested ? 'Please use ' + suggested + ' instead.' : ''; 5448 warnOnce(deprecated, deprecated + ' has been deprecated. ' + 'This may not work on native WebVR displays. ' + alternative); 5449 }; 5450 function WGLUPreserveGLState(gl, bindings, callback) { 5451 if (!bindings) { 5452 callback(gl); 5453 return; 5454 } 5455 var boundValues = []; 5456 var activeTexture = null; 5457 for (var i = 0; i < bindings.length; ++i) { 5458 var binding = bindings[i]; 5459 switch (binding) { 5460 case gl.TEXTURE_BINDING_2D: 5461 case gl.TEXTURE_BINDING_CUBE_MAP: 5462 var textureUnit = bindings[++i]; 5463 if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) { 5464 console.error("TEXTURE_BINDING_2D or TEXTURE_BINDING_CUBE_MAP must be followed by a valid texture unit"); 5465 boundValues.push(null, null); 5466 break; 5467 } 5468 if (!activeTexture) { 5469 activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE); 5470 } 5471 gl.activeTexture(textureUnit); 5472 boundValues.push(gl.getParameter(binding), null); 5473 break; 5474 case gl.ACTIVE_TEXTURE: 5475 activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE); 5476 boundValues.push(null); 5477 break; 5478 default: 5479 boundValues.push(gl.getParameter(binding)); 5480 break; 5481 } 5482 } 5483 callback(gl); 5484 for (var i = 0; i < bindings.length; ++i) { 5485 var binding = bindings[i]; 5486 var boundValue = boundValues[i]; 5487 switch (binding) { 5488 case gl.ACTIVE_TEXTURE: 5489 break; 5490 case gl.ARRAY_BUFFER_BINDING: 5491 gl.bindBuffer(gl.ARRAY_BUFFER, boundValue); 5492 break; 5493 case gl.COLOR_CLEAR_VALUE: 5494 gl.clearColor(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); 5495 break; 5496 case gl.COLOR_WRITEMASK: 5497 gl.colorMask(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); 5498 break; 5499 case gl.CURRENT_PROGRAM: 5500 gl.useProgram(boundValue); 5501 break; 5502 case gl.ELEMENT_ARRAY_BUFFER_BINDING: 5503 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, boundValue); 5504 break; 5505 case gl.FRAMEBUFFER_BINDING: 5506 gl.bindFramebuffer(gl.FRAMEBUFFER, boundValue); 5507 break; 5508 case gl.RENDERBUFFER_BINDING: 5509 gl.bindRenderbuffer(gl.RENDERBUFFER, boundValue); 5510 break; 5511 case gl.TEXTURE_BINDING_2D: 5512 var textureUnit = bindings[++i]; 5513 if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) 5514 break; 5515 gl.activeTexture(textureUnit); 5516 gl.bindTexture(gl.TEXTURE_2D, boundValue); 5517 break; 5518 case gl.TEXTURE_BINDING_CUBE_MAP: 5519 var textureUnit = bindings[++i]; 5520 if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) 5521 break; 5522 gl.activeTexture(textureUnit); 5523 gl.bindTexture(gl.TEXTURE_CUBE_MAP, boundValue); 5524 break; 5525 case gl.VIEWPORT: 5526 gl.viewport(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); 5527 break; 5528 case gl.BLEND: 5529 case gl.CULL_FACE: 5530 case gl.DEPTH_TEST: 5531 case gl.SCISSOR_TEST: 5532 case gl.STENCIL_TEST: 5533 if (boundValue) { 5534 gl.enable(binding); 5535 } else { 5536 gl.disable(binding); 5537 } 5538 break; 5539 default: 5540 console.log("No GL restore behavior for 0x" + binding.toString(16)); 5541 break; 5542 } 5543 if (activeTexture) { 5544 gl.activeTexture(activeTexture); 5545 } 5546 } 5547 } 5548 var glPreserveState = WGLUPreserveGLState; 5549 var distortionVS = ['attribute vec2 position;', 'attribute vec3 texCoord;', 'varying vec2 vTexCoord;', 'uniform vec4 viewportOffsetScale[2];', 'void main() {', ' vec4 viewport = viewportOffsetScale[int(texCoord.z)];', ' vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;', ' gl_Position = vec4( position, 1.0, 1.0 );', '}'].join('\n'); 5550 var distortionFS = ['precision mediump float;', 'uniform sampler2D diffuse;', 'varying vec2 vTexCoord;', 'void main() {', ' gl_FragColor = texture2D(diffuse, vTexCoord);', '}'].join('\n'); 5551 function CardboardDistorter(gl, cardboardUI, bufferScale, dirtySubmitFrameBindings) { 5552 this.gl = gl; 5553 this.cardboardUI = cardboardUI; 5554 this.bufferScale = bufferScale; 5555 this.dirtySubmitFrameBindings = dirtySubmitFrameBindings; 5556 this.ctxAttribs = gl.getContextAttributes(); 5557 this.meshWidth = 20; 5558 this.meshHeight = 20; 5559 this.bufferWidth = gl.drawingBufferWidth; 5560 this.bufferHeight = gl.drawingBufferHeight; 5561 this.realBindFramebuffer = gl.bindFramebuffer; 5562 this.realEnable = gl.enable; 5563 this.realDisable = gl.disable; 5564 this.realColorMask = gl.colorMask; 5565 this.realClearColor = gl.clearColor; 5566 this.realViewport = gl.viewport; 5567 if (!isIOS()) { 5568 this.realCanvasWidth = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'width'); 5569 this.realCanvasHeight = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'height'); 5570 } 5571 this.isPatched = false; 5572 this.lastBoundFramebuffer = null; 5573 this.cullFace = false; 5574 this.depthTest = false; 5575 this.blend = false; 5576 this.scissorTest = false; 5577 this.stencilTest = false; 5578 this.viewport = [0, 0, 0, 0]; 5579 this.colorMask = [true, true, true, true]; 5580 this.clearColor = [0, 0, 0, 0]; 5581 this.attribs = { 5582 position: 0, 5583 texCoord: 1 5584 }; 5585 this.program = linkProgram(gl, distortionVS, distortionFS, this.attribs); 5586 this.uniforms = getProgramUniforms(gl, this.program); 5587 this.viewportOffsetScale = new Float32Array(8); 5588 this.setTextureBounds(); 5589 this.vertexBuffer = gl.createBuffer(); 5590 this.indexBuffer = gl.createBuffer(); 5591 this.indexCount = 0; 5592 this.renderTarget = gl.createTexture(); 5593 this.framebuffer = gl.createFramebuffer(); 5594 this.depthStencilBuffer = null; 5595 this.depthBuffer = null; 5596 this.stencilBuffer = null; 5597 if (this.ctxAttribs.depth && this.ctxAttribs.stencil) { 5598 this.depthStencilBuffer = gl.createRenderbuffer(); 5599 } else if (this.ctxAttribs.depth) { 5600 this.depthBuffer = gl.createRenderbuffer(); 5601 } else if (this.ctxAttribs.stencil) { 5602 this.stencilBuffer = gl.createRenderbuffer(); 5603 } 5604 this.patch(); 5605 this.onResize(); 5606 } 5607 CardboardDistorter.prototype.destroy = function () { 5608 var gl = this.gl; 5609 this.unpatch(); 5610 gl.deleteProgram(this.program); 5611 gl.deleteBuffer(this.vertexBuffer); 5612 gl.deleteBuffer(this.indexBuffer); 5613 gl.deleteTexture(this.renderTarget); 5614 gl.deleteFramebuffer(this.framebuffer); 5615 if (this.depthStencilBuffer) { 5616 gl.deleteRenderbuffer(this.depthStencilBuffer); 5617 } 5618 if (this.depthBuffer) { 5619 gl.deleteRenderbuffer(this.depthBuffer); 5620 } 5621 if (this.stencilBuffer) { 5622 gl.deleteRenderbuffer(this.stencilBuffer); 5623 } 5624 if (this.cardboardUI) { 5625 this.cardboardUI.destroy(); 5626 } 5627 }; 5628 CardboardDistorter.prototype.onResize = function () { 5629 var gl = this.gl; 5630 var self = this; 5631 var glState = [gl.RENDERBUFFER_BINDING, gl.TEXTURE_BINDING_2D, gl.TEXTURE0]; 5632 glPreserveState(gl, glState, function (gl) { 5633 self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null); 5634 if (self.scissorTest) { 5635 self.realDisable.call(gl, gl.SCISSOR_TEST); 5636 } 5637 self.realColorMask.call(gl, true, true, true, true); 5638 self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 5639 self.realClearColor.call(gl, 0, 0, 0, 1); 5640 gl.clear(gl.COLOR_BUFFER_BIT); 5641 self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.framebuffer); 5642 gl.bindTexture(gl.TEXTURE_2D, self.renderTarget); 5643 gl.texImage2D(gl.TEXTURE_2D, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, self.bufferWidth, self.bufferHeight, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, gl.UNSIGNED_BYTE, null); 5644 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 5645 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 5646 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 5647 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 5648 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, self.renderTarget, 0); 5649 if (self.ctxAttribs.depth && self.ctxAttribs.stencil) { 5650 gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthStencilBuffer); 5651 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, self.bufferWidth, self.bufferHeight); 5652 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, self.depthStencilBuffer); 5653 } else if (self.ctxAttribs.depth) { 5654 gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthBuffer); 5655 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, self.bufferWidth, self.bufferHeight); 5656 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, self.depthBuffer); 5657 } else if (self.ctxAttribs.stencil) { 5658 gl.bindRenderbuffer(gl.RENDERBUFFER, self.stencilBuffer); 5659 gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, self.bufferWidth, self.bufferHeight); 5660 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, self.stencilBuffer); 5661 } 5662 if (!gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) { 5663 console.error('Framebuffer incomplete!'); 5664 } 5665 self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer); 5666 if (self.scissorTest) { 5667 self.realEnable.call(gl, gl.SCISSOR_TEST); 5668 } 5669 self.realColorMask.apply(gl, self.colorMask); 5670 self.realViewport.apply(gl, self.viewport); 5671 self.realClearColor.apply(gl, self.clearColor); 5672 }); 5673 if (this.cardboardUI) { 5674 this.cardboardUI.onResize(); 5675 } 5676 }; 5677 CardboardDistorter.prototype.patch = function () { 5678 if (this.isPatched) { 5679 return; 5680 } 5681 var self = this; 5682 var canvas = this.gl.canvas; 5683 var gl = this.gl; 5684 if (!isIOS()) { 5685 canvas.width = getScreenWidth() * this.bufferScale; 5686 canvas.height = getScreenHeight() * this.bufferScale; 5687 Object.defineProperty(canvas, 'width', { 5688 configurable: true, 5689 enumerable: true, 5690 get: function get() { 5691 return self.bufferWidth; 5692 }, 5693 set: function set(value) { 5694 self.bufferWidth = value; 5695 self.realCanvasWidth.set.call(canvas, value); 5696 self.onResize(); 5697 } 5698 }); 5699 Object.defineProperty(canvas, 'height', { 5700 configurable: true, 5701 enumerable: true, 5702 get: function get() { 5703 return self.bufferHeight; 5704 }, 5705 set: function set(value) { 5706 self.bufferHeight = value; 5707 self.realCanvasHeight.set.call(canvas, value); 5708 self.onResize(); 5709 } 5710 }); 5711 } 5712 this.lastBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); 5713 if (this.lastBoundFramebuffer == null) { 5714 this.lastBoundFramebuffer = this.framebuffer; 5715 this.gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); 5716 } 5717 this.gl.bindFramebuffer = function (target, framebuffer) { 5718 self.lastBoundFramebuffer = framebuffer ? framebuffer : self.framebuffer; 5719 self.realBindFramebuffer.call(gl, target, self.lastBoundFramebuffer); 5720 }; 5721 this.cullFace = gl.getParameter(gl.CULL_FACE); 5722 this.depthTest = gl.getParameter(gl.DEPTH_TEST); 5723 this.blend = gl.getParameter(gl.BLEND); 5724 this.scissorTest = gl.getParameter(gl.SCISSOR_TEST); 5725 this.stencilTest = gl.getParameter(gl.STENCIL_TEST); 5726 gl.enable = function (pname) { 5727 switch (pname) { 5728 case gl.CULL_FACE: 5729 self.cullFace = true;break; 5730 case gl.DEPTH_TEST: 5731 self.depthTest = true;break; 5732 case gl.BLEND: 5733 self.blend = true;break; 5734 case gl.SCISSOR_TEST: 5735 self.scissorTest = true;break; 5736 case gl.STENCIL_TEST: 5737 self.stencilTest = true;break; 5738 } 5739 self.realEnable.call(gl, pname); 5740 }; 5741 gl.disable = function (pname) { 5742 switch (pname) { 5743 case gl.CULL_FACE: 5744 self.cullFace = false;break; 5745 case gl.DEPTH_TEST: 5746 self.depthTest = false;break; 5747 case gl.BLEND: 5748 self.blend = false;break; 5749 case gl.SCISSOR_TEST: 5750 self.scissorTest = false;break; 5751 case gl.STENCIL_TEST: 5752 self.stencilTest = false;break; 5753 } 5754 self.realDisable.call(gl, pname); 5755 };
vendor: 13,898 bytes, lines 5756-6120
5756 this.colorMask = gl.getParameter(gl.COLOR_WRITEMASK); 5757 gl.colorMask = function (r, g, b, a) { 5758 self.colorMask[0] = r; 5759 self.colorMask[1] = g; 5760 self.colorMask[2] = b; 5761 self.colorMask[3] = a; 5762 self.realColorMask.call(gl, r, g, b, a); 5763 }; 5764 this.clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE); 5765 gl.clearColor = function (r, g, b, a) { 5766 self.clearColor[0] = r; 5767 self.clearColor[1] = g; 5768 self.clearColor[2] = b; 5769 self.clearColor[3] = a; 5770 self.realClearColor.call(gl, r, g, b, a); 5771 }; 5772 this.viewport = gl.getParameter(gl.VIEWPORT); 5773 gl.viewport = function (x, y, w, h) { 5774 self.viewport[0] = x; 5775 self.viewport[1] = y; 5776 self.viewport[2] = w; 5777 self.viewport[3] = h; 5778 self.realViewport.call(gl, x, y, w, h); 5779 }; 5780 this.isPatched = true; 5781 safariCssSizeWorkaround(canvas); 5782 }; 5783 CardboardDistorter.prototype.unpatch = function () { 5784 if (!this.isPatched) { 5785 return; 5786 } 5787 var gl = this.gl; 5788 var canvas = this.gl.canvas; 5789 if (!isIOS()) { 5790 Object.defineProperty(canvas, 'width', this.realCanvasWidth); 5791 Object.defineProperty(canvas, 'height', this.realCanvasHeight); 5792 } 5793 canvas.width = this.bufferWidth; 5794 canvas.height = this.bufferHeight; 5795 gl.bindFramebuffer = this.realBindFramebuffer; 5796 gl.enable = this.realEnable; 5797 gl.disable = this.realDisable; 5798 gl.colorMask = this.realColorMask; 5799 gl.clearColor = this.realClearColor; 5800 gl.viewport = this.realViewport; 5801 if (this.lastBoundFramebuffer == this.framebuffer) { 5802 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 5803 } 5804 this.isPatched = false; 5805 setTimeout(function () { 5806 safariCssSizeWorkaround(canvas); 5807 }, 1); 5808 }; 5809 CardboardDistorter.prototype.setTextureBounds = function (leftBounds, rightBounds) { 5810 if (!leftBounds) { 5811 leftBounds = [0, 0, 0.5, 1]; 5812 } 5813 if (!rightBounds) { 5814 rightBounds = [0.5, 0, 0.5, 1]; 5815 } 5816 this.viewportOffsetScale[0] = leftBounds[0]; 5817 this.viewportOffsetScale[1] = leftBounds[1]; 5818 this.viewportOffsetScale[2] = leftBounds[2]; 5819 this.viewportOffsetScale[3] = leftBounds[3]; 5820 this.viewportOffsetScale[4] = rightBounds[0]; 5821 this.viewportOffsetScale[5] = rightBounds[1]; 5822 this.viewportOffsetScale[6] = rightBounds[2]; 5823 this.viewportOffsetScale[7] = rightBounds[3]; 5824 }; 5825 CardboardDistorter.prototype.submitFrame = function () { 5826 var gl = this.gl; 5827 var self = this; 5828 var glState = []; 5829 if (!this.dirtySubmitFrameBindings) { 5830 glState.push(gl.CURRENT_PROGRAM, gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING, gl.TEXTURE_BINDING_2D, gl.TEXTURE0); 5831 } 5832 glPreserveState(gl, glState, function (gl) { 5833 self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null); 5834 if (self.cullFace) { 5835 self.realDisable.call(gl, gl.CULL_FACE); 5836 } 5837 if (self.depthTest) { 5838 self.realDisable.call(gl, gl.DEPTH_TEST); 5839 } 5840 if (self.blend) { 5841 self.realDisable.call(gl, gl.BLEND); 5842 } 5843 if (self.scissorTest) { 5844 self.realDisable.call(gl, gl.SCISSOR_TEST); 5845 } 5846 if (self.stencilTest) { 5847 self.realDisable.call(gl, gl.STENCIL_TEST); 5848 } 5849 self.realColorMask.call(gl, true, true, true, true); 5850 self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 5851 if (self.ctxAttribs.alpha || isIOS()) { 5852 self.realClearColor.call(gl, 0, 0, 0, 1); 5853 gl.clear(gl.COLOR_BUFFER_BIT); 5854 } 5855 gl.useProgram(self.program); 5856 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer); 5857 gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); 5858 gl.enableVertexAttribArray(self.attribs.position); 5859 gl.enableVertexAttribArray(self.attribs.texCoord); 5860 gl.vertexAttribPointer(self.attribs.position, 2, gl.FLOAT, false, 20, 0); 5861 gl.vertexAttribPointer(self.attribs.texCoord, 3, gl.FLOAT, false, 20, 8); 5862 gl.activeTexture(gl.TEXTURE0); 5863 gl.uniform1i(self.uniforms.diffuse, 0); 5864 gl.bindTexture(gl.TEXTURE_2D, self.renderTarget); 5865 gl.uniform4fv(self.uniforms.viewportOffsetScale, self.viewportOffsetScale); 5866 gl.drawElements(gl.TRIANGLES, self.indexCount, gl.UNSIGNED_SHORT, 0); 5867 if (self.cardboardUI) { 5868 self.cardboardUI.renderNoState(); 5869 } 5870 self.realBindFramebuffer.call(self.gl, gl.FRAMEBUFFER, self.framebuffer); 5871 if (!self.ctxAttribs.preserveDrawingBuffer) { 5872 self.realClearColor.call(gl, 0, 0, 0, 0); 5873 gl.clear(gl.COLOR_BUFFER_BIT); 5874 } 5875 if (!self.dirtySubmitFrameBindings) { 5876 self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer); 5877 } 5878 if (self.cullFace) { 5879 self.realEnable.call(gl, gl.CULL_FACE); 5880 } 5881 if (self.depthTest) { 5882 self.realEnable.call(gl, gl.DEPTH_TEST); 5883 } 5884 if (self.blend) { 5885 self.realEnable.call(gl, gl.BLEND); 5886 } 5887 if (self.scissorTest) { 5888 self.realEnable.call(gl, gl.SCISSOR_TEST); 5889 } 5890 if (self.stencilTest) { 5891 self.realEnable.call(gl, gl.STENCIL_TEST); 5892 } 5893 self.realColorMask.apply(gl, self.colorMask); 5894 self.realViewport.apply(gl, self.viewport); 5895 if (self.ctxAttribs.alpha || !self.ctxAttribs.preserveDrawingBuffer) { 5896 self.realClearColor.apply(gl, self.clearColor); 5897 } 5898 }); 5899 if (isIOS()) { 5900 var canvas = gl.canvas; 5901 if (canvas.width != self.bufferWidth || canvas.height != self.bufferHeight) { 5902 self.bufferWidth = canvas.width; 5903 self.bufferHeight = canvas.height; 5904 self.onResize(); 5905 } 5906 } 5907 }; 5908 CardboardDistorter.prototype.updateDeviceInfo = function (deviceInfo) { 5909 var gl = this.gl; 5910 var self = this; 5911 var glState = [gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING]; 5912 glPreserveState(gl, glState, function (gl) { 5913 var vertices = self.computeMeshVertices_(self.meshWidth, self.meshHeight, deviceInfo); 5914 gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); 5915 gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 5916 if (!self.indexCount) { 5917 var indices = self.computeMeshIndices_(self.meshWidth, self.meshHeight); 5918 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer); 5919 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); 5920 self.indexCount = indices.length; 5921 } 5922 }); 5923 }; 5924 CardboardDistorter.prototype.computeMeshVertices_ = function (width, height, deviceInfo) { 5925 var vertices = new Float32Array(2 * width * height * 5); 5926 var lensFrustum = deviceInfo.getLeftEyeVisibleTanAngles(); 5927 var noLensFrustum = deviceInfo.getLeftEyeNoLensTanAngles(); 5928 var viewport = deviceInfo.getLeftEyeVisibleScreenRect(noLensFrustum); 5929 var vidx = 0; 5930 for (var e = 0; e < 2; e++) { 5931 for (var j = 0; j < height; j++) { 5932 for (var i = 0; i < width; i++, vidx++) { 5933 var u = i / (width - 1); 5934 var v = j / (height - 1); 5935 var s = u; 5936 var t = v; 5937 var x = lerp(lensFrustum[0], lensFrustum[2], u); 5938 var y = lerp(lensFrustum[3], lensFrustum[1], v); 5939 var d = Math.sqrt(x * x + y * y); 5940 var r = deviceInfo.distortion.distortInverse(d); 5941 var p = x * r / d; 5942 var q = y * r / d; 5943 u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]); 5944 v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]); 5945 u = (viewport.x + u * viewport.width - 0.5) * 2.0; 5946 v = (viewport.y + v * viewport.height - 0.5) * 2.0; 5947 vertices[vidx * 5 + 0] = u; 5948 vertices[vidx * 5 + 1] = v; 5949 vertices[vidx * 5 + 2] = s; 5950 vertices[vidx * 5 + 3] = t; 5951 vertices[vidx * 5 + 4] = e; 5952 } 5953 } 5954 var w = lensFrustum[2] - lensFrustum[0]; 5955 lensFrustum[0] = -(w + lensFrustum[0]); 5956 lensFrustum[2] = w - lensFrustum[2]; 5957 w = noLensFrustum[2] - noLensFrustum[0]; 5958 noLensFrustum[0] = -(w + noLensFrustum[0]); 5959 noLensFrustum[2] = w - noLensFrustum[2]; 5960 viewport.x = 1 - (viewport.x + viewport.width); 5961 } 5962 return vertices; 5963 }; 5964 CardboardDistorter.prototype.computeMeshIndices_ = function (width, height) { 5965 var indices = new Uint16Array(2 * (width - 1) * (height - 1) * 6); 5966 var halfwidth = width / 2; 5967 var halfheight = height / 2; 5968 var vidx = 0; 5969 var iidx = 0; 5970 for (var e = 0; e < 2; e++) { 5971 for (var j = 0; j < height; j++) { 5972 for (var i = 0; i < width; i++, vidx++) { 5973 if (i == 0 || j == 0) continue; 5974 if (i <= halfwidth == j <= halfheight) { 5975 indices[iidx++] = vidx; 5976 indices[iidx++] = vidx - width - 1; 5977 indices[iidx++] = vidx - width; 5978 indices[iidx++] = vidx - width - 1; 5979 indices[iidx++] = vidx; 5980 indices[iidx++] = vidx - 1; 5981 } else { 5982 indices[iidx++] = vidx - 1; 5983 indices[iidx++] = vidx - width; 5984 indices[iidx++] = vidx; 5985 indices[iidx++] = vidx - width; 5986 indices[iidx++] = vidx - 1; 5987 indices[iidx++] = vidx - width - 1; 5988 } 5989 } 5990 } 5991 } 5992 return indices; 5993 }; 5994 CardboardDistorter.prototype.getOwnPropertyDescriptor_ = function (proto, attrName) { 5995 var descriptor = Object.getOwnPropertyDescriptor(proto, attrName); 5996 if (descriptor.get === undefined || descriptor.set === undefined) { 5997 descriptor.configurable = true; 5998 descriptor.enumerable = true; 5999 descriptor.get = function () { 6000 return this.getAttribute(attrName); 6001 }; 6002 descriptor.set = function (val) { 6003 this.setAttribute(attrName, val); 6004 }; 6005 } 6006 return descriptor; 6007 }; 6008 var uiVS = ['attribute vec2 position;', 'uniform mat4 projectionMat;', 'void main() {', ' gl_Position = projectionMat * vec4( position, -1.0, 1.0 );', '}'].join('\n'); 6009 var uiFS = ['precision mediump float;', 'uniform vec4 color;', 'void main() {', ' gl_FragColor = color;', '}'].join('\n'); 6010 var DEG2RAD = Math.PI / 180.0; 6011 var kAnglePerGearSection = 60; 6012 var kOuterRimEndAngle = 12; 6013 var kInnerRimBeginAngle = 20; 6014 var kOuterRadius = 1; 6015 var kMiddleRadius = 0.75; 6016 var kInnerRadius = 0.3125; 6017 var kCenterLineThicknessDp = 4; 6018 var kButtonWidthDp = 28; 6019 var kTouchSlopFactor = 1.5; 6020 function CardboardUI(gl) { 6021 this.gl = gl; 6022 this.attribs = { 6023 position: 0 6024 }; 6025 this.program = linkProgram(gl, uiVS, uiFS, this.attribs); 6026 this.uniforms = getProgramUniforms(gl, this.program); 6027 this.vertexBuffer = gl.createBuffer(); 6028 this.gearOffset = 0; 6029 this.gearVertexCount = 0; 6030 this.arrowOffset = 0; 6031 this.arrowVertexCount = 0; 6032 this.projMat = new Float32Array(16); 6033 this.listener = null; 6034 this.onResize(); 6035 } 6036 CardboardUI.prototype.destroy = function () { 6037 var gl = this.gl; 6038 if (this.listener) { 6039 gl.canvas.removeEventListener('click', this.listener, false); 6040 } 6041 gl.deleteProgram(this.program); 6042 gl.deleteBuffer(this.vertexBuffer); 6043 }; 6044 CardboardUI.prototype.listen = function (optionsCallback, backCallback) { 6045 var canvas = this.gl.canvas; 6046 this.listener = function (event) { 6047 var midline = canvas.clientWidth / 2; 6048 var buttonSize = kButtonWidthDp * kTouchSlopFactor; 6049 if (event.clientX > midline - buttonSize && event.clientX < midline + buttonSize && event.clientY > canvas.clientHeight - buttonSize) { 6050 optionsCallback(event); 6051 } 6052 else if (event.clientX < buttonSize && event.clientY < buttonSize) { 6053 backCallback(event); 6054 } 6055 }; 6056 canvas.addEventListener('click', this.listener, false); 6057 }; 6058 CardboardUI.prototype.onResize = function () { 6059 var gl = this.gl; 6060 var self = this; 6061 var glState = [gl.ARRAY_BUFFER_BINDING]; 6062 glPreserveState(gl, glState, function (gl) { 6063 var vertices = []; 6064 var midline = gl.drawingBufferWidth / 2; 6065 var physicalPixels = Math.max(screen.width, screen.height) * window.devicePixelRatio; 6066 var scalingRatio = gl.drawingBufferWidth / physicalPixels; 6067 var dps = scalingRatio * window.devicePixelRatio; 6068 var lineWidth = kCenterLineThicknessDp * dps / 2; 6069 var buttonSize = kButtonWidthDp * kTouchSlopFactor * dps; 6070 var buttonScale = kButtonWidthDp * dps / 2; 6071 var buttonBorder = (kButtonWidthDp * kTouchSlopFactor - kButtonWidthDp) * dps; 6072 vertices.push(midline - lineWidth, buttonSize); 6073 vertices.push(midline - lineWidth, gl.drawingBufferHeight); 6074 vertices.push(midline + lineWidth, buttonSize); 6075 vertices.push(midline + lineWidth, gl.drawingBufferHeight); 6076 self.gearOffset = vertices.length / 2; 6077 function addGearSegment(theta, r) { 6078 var angle = (90 - theta) * DEG2RAD; 6079 var x = Math.cos(angle); 6080 var y = Math.sin(angle); 6081 vertices.push(kInnerRadius * x * buttonScale + midline, kInnerRadius * y * buttonScale + buttonScale); 6082 vertices.push(r * x * buttonScale + midline, r * y * buttonScale + buttonScale); 6083 } 6084 for (var i = 0; i <= 6; i++) { 6085 var segmentTheta = i * kAnglePerGearSection; 6086 addGearSegment(segmentTheta, kOuterRadius); 6087 addGearSegment(segmentTheta + kOuterRimEndAngle, kOuterRadius); 6088 addGearSegment(segmentTheta + kInnerRimBeginAngle, kMiddleRadius); 6089 addGearSegment(segmentTheta + (kAnglePerGearSection - kInnerRimBeginAngle), kMiddleRadius); 6090 addGearSegment(segmentTheta + (kAnglePerGearSection - kOuterRimEndAngle), kOuterRadius); 6091 } 6092 self.gearVertexCount = vertices.length / 2 - self.gearOffset; 6093 self.arrowOffset = vertices.length / 2; 6094 function addArrowVertex(x, y) { 6095 vertices.push(buttonBorder + x, gl.drawingBufferHeight - buttonBorder - y); 6096 } 6097 var angledLineWidth = lineWidth / Math.sin(45 * DEG2RAD); 6098 addArrowVertex(0, buttonScale); 6099 addArrowVertex(buttonScale, 0); 6100 addArrowVertex(buttonScale + angledLineWidth, angledLineWidth); 6101 addArrowVertex(angledLineWidth, buttonScale + angledLineWidth); 6102 addArrowVertex(angledLineWidth, buttonScale - angledLineWidth); 6103 addArrowVertex(0, buttonScale); 6104 addArrowVertex(buttonScale, buttonScale * 2); 6105 addArrowVertex(buttonScale + angledLineWidth, buttonScale * 2 - angledLineWidth); 6106 addArrowVertex(angledLineWidth, buttonScale - angledLineWidth); 6107 addArrowVertex(0, buttonScale); 6108 addArrowVertex(angledLineWidth, buttonScale - lineWidth); 6109 addArrowVertex(kButtonWidthDp * dps, buttonScale - lineWidth); 6110 addArrowVertex(angledLineWidth, buttonScale + lineWidth); 6111 addArrowVertex(kButtonWidthDp * dps, buttonScale + lineWidth); 6112 self.arrowVertexCount = vertices.length / 2 - self.arrowOffset; 6113 gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); 6114 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 6115 }); 6116 }; 6117 CardboardUI.prototype.render = function () { 6118 var gl = this.gl; 6119 var self = this; 6120 var glState = [gl.CULL_FACE, gl.DEPTH_TEST, gl.BLEND, gl.SCISSOR_TEST, gl.STENCIL_TEST, gl.COLOR_WRITEMA
vendor: 18,151 bytes, lines 6120-6650
6120SK, gl.VIEWPORT, gl.CURRENT_PROGRAM, gl.ARRAY_BUFFER_BINDING]; 6121 glPreserveState(gl, glState, function (gl) { 6122 gl.disable(gl.CULL_FACE); 6123 gl.disable(gl.DEPTH_TEST); 6124 gl.disable(gl.BLEND); 6125 gl.disable(gl.SCISSOR_TEST); 6126 gl.disable(gl.STENCIL_TEST); 6127 gl.colorMask(true, true, true, true); 6128 gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 6129 self.renderNoState(); 6130 }); 6131 }; 6132 CardboardUI.prototype.renderNoState = function () { 6133 var gl = this.gl; 6134 gl.useProgram(this.program); 6135 gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); 6136 gl.enableVertexAttribArray(this.attribs.position); 6137 gl.vertexAttribPointer(this.attribs.position, 2, gl.FLOAT, false, 8, 0); 6138 gl.uniform4f(this.uniforms.color, 1.0, 1.0, 1.0, 1.0); 6139 orthoMatrix(this.projMat, 0, gl.drawingBufferWidth, 0, gl.drawingBufferHeight, 0.1, 1024.0); 6140 gl.uniformMatrix4fv(this.uniforms.projectionMat, false, this.projMat); 6141 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 6142 gl.drawArrays(gl.TRIANGLE_STRIP, this.gearOffset, this.gearVertexCount); 6143 gl.drawArrays(gl.TRIANGLE_STRIP, this.arrowOffset, this.arrowVertexCount); 6144 }; 6145 function Distortion(coefficients) { 6146 this.coefficients = coefficients; 6147 } 6148 Distortion.prototype.distortInverse = function (radius) { 6149 var r0 = 0; 6150 var r1 = 1; 6151 var dr0 = radius - this.distort(r0); 6152 while (Math.abs(r1 - r0) > 0.0001 ) { 6153 var dr1 = radius - this.distort(r1); 6154 var r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0)); 6155 r0 = r1; 6156 r1 = r2; 6157 dr0 = dr1; 6158 } 6159 return r1; 6160 }; 6161 Distortion.prototype.distort = function (radius) { 6162 var r2 = radius * radius; 6163 var ret = 0; 6164 for (var i = 0; i < this.coefficients.length; i++) { 6165 ret = r2 * (ret + this.coefficients[i]); 6166 } 6167 return (ret + 1) * radius; 6168 }; 6169 var degToRad = Math.PI / 180; 6170 var radToDeg = 180 / Math.PI; 6171 var Vector3 = function Vector3(x, y, z) { 6172 this.x = x || 0; 6173 this.y = y || 0; 6174 this.z = z || 0; 6175 }; 6176 Vector3.prototype = { 6177 constructor: Vector3, 6178 set: function set(x, y, z) { 6179 this.x = x; 6180 this.y = y; 6181 this.z = z; 6182 return this; 6183 }, 6184 copy: function copy(v) { 6185 this.x = v.x; 6186 this.y = v.y; 6187 this.z = v.z; 6188 return this; 6189 }, 6190 length: function length() { 6191 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 6192 }, 6193 normalize: function normalize() { 6194 var scalar = this.length(); 6195 if (scalar !== 0) { 6196 var invScalar = 1 / scalar; 6197 this.multiplyScalar(invScalar); 6198 } else { 6199 this.x = 0; 6200 this.y = 0; 6201 this.z = 0; 6202 } 6203 return this; 6204 }, 6205 multiplyScalar: function multiplyScalar(scalar) { 6206 this.x *= scalar; 6207 this.y *= scalar; 6208 this.z *= scalar; 6209 }, 6210 applyQuaternion: function applyQuaternion(q) { 6211 var x = this.x; 6212 var y = this.y; 6213 var z = this.z; 6214 var qx = q.x; 6215 var qy = q.y; 6216 var qz = q.z; 6217 var qw = q.w; 6218 var ix = qw * x + qy * z - qz * y; 6219 var iy = qw * y + qz * x - qx * z; 6220 var iz = qw * z + qx * y - qy * x; 6221 var iw = -qx * x - qy * y - qz * z; 6222 this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; 6223 this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; 6224 this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; 6225 return this; 6226 }, 6227 dot: function dot(v) { 6228 return this.x * v.x + this.y * v.y + this.z * v.z; 6229 }, 6230 crossVectors: function crossVectors(a, b) { 6231 var ax = a.x, 6232 ay = a.y, 6233 az = a.z; 6234 var bx = b.x, 6235 by = b.y, 6236 bz = b.z; 6237 this.x = ay * bz - az * by; 6238 this.y = az * bx - ax * bz; 6239 this.z = ax * by - ay * bx; 6240 return this; 6241 } 6242 }; 6243 var Quaternion = function Quaternion(x, y, z, w) { 6244 this.x = x || 0; 6245 this.y = y || 0; 6246 this.z = z || 0; 6247 this.w = w !== undefined ? w : 1; 6248 }; 6249 Quaternion.prototype = { 6250 constructor: Quaternion, 6251 set: function set(x, y, z, w) { 6252 this.x = x; 6253 this.y = y; 6254 this.z = z; 6255 this.w = w; 6256 return this; 6257 }, 6258 copy: function copy(quaternion) { 6259 this.x = quaternion.x; 6260 this.y = quaternion.y; 6261 this.z = quaternion.z; 6262 this.w = quaternion.w; 6263 return this; 6264 }, 6265 setFromEulerXYZ: function setFromEulerXYZ(x, y, z) { 6266 var c1 = Math.cos(x / 2); 6267 var c2 = Math.cos(y / 2); 6268 var c3 = Math.cos(z / 2); 6269 var s1 = Math.sin(x / 2); 6270 var s2 = Math.sin(y / 2); 6271 var s3 = Math.sin(z / 2); 6272 this.x = s1 * c2 * c3 + c1 * s2 * s3; 6273 this.y = c1 * s2 * c3 - s1 * c2 * s3; 6274 this.z = c1 * c2 * s3 + s1 * s2 * c3; 6275 this.w = c1 * c2 * c3 - s1 * s2 * s3; 6276 return this; 6277 }, 6278 setFromEulerYXZ: function setFromEulerYXZ(x, y, z) { 6279 var c1 = Math.cos(x / 2); 6280 var c2 = Math.cos(y / 2); 6281 var c3 = Math.cos(z / 2); 6282 var s1 = Math.sin(x / 2); 6283 var s2 = Math.sin(y / 2); 6284 var s3 = Math.sin(z / 2); 6285 this.x = s1 * c2 * c3 + c1 * s2 * s3; 6286 this.y = c1 * s2 * c3 - s1 * c2 * s3; 6287 this.z = c1 * c2 * s3 - s1 * s2 * c3; 6288 this.w = c1 * c2 * c3 + s1 * s2 * s3; 6289 return this; 6290 }, 6291 setFromAxisAngle: function setFromAxisAngle(axis, angle) { 6292 var halfAngle = angle / 2, 6293 s = Math.sin(halfAngle); 6294 this.x = axis.x * s; 6295 this.y = axis.y * s; 6296 this.z = axis.z * s; 6297 this.w = Math.cos(halfAngle); 6298 return this; 6299 }, 6300 multiply: function multiply(q) { 6301 return this.multiplyQuaternions(this, q); 6302 }, 6303 multiplyQuaternions: function multiplyQuaternions(a, b) { 6304 var qax = a.x, 6305 qay = a.y, 6306 qaz = a.z, 6307 qaw = a.w; 6308 var qbx = b.x, 6309 qby = b.y, 6310 qbz = b.z, 6311 qbw = b.w; 6312 this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 6313 this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 6314 this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 6315 this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 6316 return this; 6317 }, 6318 inverse: function inverse() { 6319 this.x *= -1; 6320 this.y *= -1; 6321 this.z *= -1; 6322 this.normalize(); 6323 return this; 6324 }, 6325 normalize: function normalize() { 6326 var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); 6327 if (l === 0) { 6328 this.x = 0; 6329 this.y = 0; 6330 this.z = 0; 6331 this.w = 1; 6332 } else { 6333 l = 1 / l; 6334 this.x = this.x * l; 6335 this.y = this.y * l; 6336 this.z = this.z * l; 6337 this.w = this.w * l; 6338 } 6339 return this; 6340 }, 6341 slerp: function slerp(qb, t) { 6342 if (t === 0) return this; 6343 if (t === 1) return this.copy(qb); 6344 var x = this.x, 6345 y = this.y, 6346 z = this.z, 6347 w = this.w; 6348 var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; 6349 if (cosHalfTheta < 0) { 6350 this.w = -qb.w; 6351 this.x = -qb.x; 6352 this.y = -qb.y; 6353 this.z = -qb.z; 6354 cosHalfTheta = -cosHalfTheta; 6355 } else { 6356 this.copy(qb); 6357 } 6358 if (cosHalfTheta >= 1.0) { 6359 this.w = w; 6360 this.x = x; 6361 this.y = y; 6362 this.z = z; 6363 return this; 6364 } 6365 var halfTheta = Math.acos(cosHalfTheta); 6366 var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); 6367 if (Math.abs(sinHalfTheta) < 0.001) { 6368 this.w = 0.5 * (w + this.w); 6369 this.x = 0.5 * (x + this.x); 6370 this.y = 0.5 * (y + this.y); 6371 this.z = 0.5 * (z + this.z); 6372 return this; 6373 } 6374 var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, 6375 ratioB = Math.sin(t * halfTheta) / sinHalfTheta; 6376 this.w = w * ratioA + this.w * ratioB; 6377 this.x = x * ratioA + this.x * ratioB; 6378 this.y = y * ratioA + this.y * ratioB; 6379 this.z = z * ratioA + this.z * ratioB; 6380 return this; 6381 }, 6382 setFromUnitVectors: function () { 6383 var v1, r; 6384 var EPS = 0.000001; 6385 return function (vFrom, vTo) { 6386 if (v1 === undefined) v1 = new Vector3(); 6387 r = vFrom.dot(vTo) + 1; 6388 if (r < EPS) { 6389 r = 0; 6390 if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { 6391 v1.set(-vFrom.y, vFrom.x, 0); 6392 } else { 6393 v1.set(0, -vFrom.z, vFrom.y); 6394 } 6395 } else { 6396 v1.crossVectors(vFrom, vTo); 6397 } 6398 this.x = v1.x; 6399 this.y = v1.y; 6400 this.z = v1.z; 6401 this.w = r; 6402 this.normalize(); 6403 return this; 6404 }; 6405 }() 6406 }; 6407 function Device(params) { 6408 this.width = params.width || getScreenWidth(); 6409 this.height = params.height || getScreenHeight(); 6410 this.widthMeters = params.widthMeters; 6411 this.heightMeters = params.heightMeters; 6412 this.bevelMeters = params.bevelMeters; 6413 } 6414 var DEFAULT_ANDROID = new Device({ 6415 widthMeters: 0.110, 6416 heightMeters: 0.062, 6417 bevelMeters: 0.004 6418 }); 6419 var DEFAULT_IOS = new Device({ 6420 widthMeters: 0.1038, 6421 heightMeters: 0.0584, 6422 bevelMeters: 0.004 6423 }); 6424 var Viewers = { 6425 CardboardV1: new CardboardViewer({ 6426 id: 'CardboardV1', 6427 label: 'Cardboard I/O 2014', 6428 fov: 40, 6429 interLensDistance: 0.060, 6430 baselineLensDistance: 0.035, 6431 screenLensDistance: 0.042, 6432 distortionCoefficients: [0.441, 0.156], 6433 inverseCoefficients: [-0.4410035, 0.42756155, -0.4804439, 0.5460139, -0.58821183, 0.5733938, -0.48303202, 0.33299083, -0.17573841, 0.0651772, -0.01488963, 0.001559834] 6434 }), 6435 CardboardV2: new CardboardViewer({ 6436 id: 'CardboardV2', 6437 label: 'Cardboard I/O 2015', 6438 fov: 60, 6439 interLensDistance: 0.064, 6440 baselineLensDistance: 0.035, 6441 screenLensDistance: 0.039, 6442 distortionCoefficients: [0.34, 0.55], 6443 inverseCoefficients: [-0.33836704, -0.18162185, 0.862655, -1.2462051, 1.0560602, -0.58208317, 0.21609078, -0.05444823, 0.009177956, -9.904169E-4, 6.183535E-5, -1.6981803E-6] 6444 }) 6445 }; 6446 function DeviceInfo(deviceParams, additionalViewers) { 6447 this.viewer = Viewers.CardboardV2; 6448 this.updateDeviceParams(deviceParams); 6449 this.distortion = new Distortion(this.viewer.distortionCoefficients); 6450 for (var i = 0; i < additionalViewers.length; i++) { 6451 var viewer = additionalViewers[i]; 6452 Viewers[viewer.id] = new CardboardViewer(viewer); 6453 } 6454 } 6455 DeviceInfo.prototype.updateDeviceParams = function (deviceParams) { 6456 this.device = this.determineDevice_(deviceParams) || this.device; 6457 }; 6458 DeviceInfo.prototype.getDevice = function () { 6459 return this.device; 6460 }; 6461 DeviceInfo.prototype.setViewer = function (viewer) { 6462 this.viewer = viewer; 6463 this.distortion = new Distortion(this.viewer.distortionCoefficients); 6464 }; 6465 DeviceInfo.prototype.determineDevice_ = function (deviceParams) { 6466 if (!deviceParams) { 6467 if (isIOS()) { 6468 console.warn('Using fallback iOS device measurements.'); 6469 return DEFAULT_IOS; 6470 } else { 6471 console.warn('Using fallback Android device measurements.'); 6472 return DEFAULT_ANDROID; 6473 } 6474 } 6475 var METERS_PER_INCH = 0.0254; 6476 var metersPerPixelX = METERS_PER_INCH / deviceParams.xdpi; 6477 var metersPerPixelY = METERS_PER_INCH / deviceParams.ydpi; 6478 var width = getScreenWidth(); 6479 var height = getScreenHeight(); 6480 return new Device({ 6481 widthMeters: metersPerPixelX * width, 6482 heightMeters: metersPerPixelY * height, 6483 bevelMeters: deviceParams.bevelMm * 0.001 6484 }); 6485 }; 6486 DeviceInfo.prototype.getDistortedFieldOfViewLeftEye = function () { 6487 var viewer = this.viewer; 6488 var device = this.device; 6489 var distortion = this.distortion; 6490 var eyeToScreenDistance = viewer.screenLensDistance; 6491 var outerDist = (device.widthMeters - viewer.interLensDistance) / 2; 6492 var innerDist = viewer.interLensDistance / 2; 6493 var bottomDist = viewer.baselineLensDistance - device.bevelMeters; 6494 var topDist = device.heightMeters - bottomDist; 6495 var outerAngle = radToDeg * Math.atan(distortion.distort(outerDist / eyeToScreenDistance)); 6496 var innerAngle = radToDeg * Math.atan(distortion.distort(innerDist / eyeToScreenDistance)); 6497 var bottomAngle = radToDeg * Math.atan(distortion.distort(bottomDist / eyeToScreenDistance)); 6498 var topAngle = radToDeg * Math.atan(distortion.distort(topDist / eyeToScreenDistance)); 6499 return { 6500 leftDegrees: Math.min(outerAngle, viewer.fov), 6501 rightDegrees: Math.min(innerAngle, viewer.fov), 6502 downDegrees: Math.min(bottomAngle, viewer.fov), 6503 upDegrees: Math.min(topAngle, viewer.fov) 6504 }; 6505 }; 6506 DeviceInfo.prototype.getLeftEyeVisibleTanAngles = function () { 6507 var viewer = this.viewer; 6508 var device = this.device; 6509 var distortion = this.distortion; 6510 var fovLeft = Math.tan(-degToRad * viewer.fov); 6511 var fovTop = Math.tan(degToRad * viewer.fov); 6512 var fovRight = Math.tan(degToRad * viewer.fov); 6513 var fovBottom = Math.tan(-degToRad * viewer.fov); 6514 var halfWidth = device.widthMeters / 4; 6515 var halfHeight = device.heightMeters / 2; 6516 var verticalLensOffset = viewer.baselineLensDistance - device.bevelMeters - halfHeight; 6517 var centerX = viewer.interLensDistance / 2 - halfWidth; 6518 var centerY = -verticalLensOffset; 6519 var centerZ = viewer.screenLensDistance; 6520 var screenLeft = distortion.distort((centerX - halfWidth) / centerZ); 6521 var screenTop = distortion.distort((centerY + halfHeight) / centerZ); 6522 var screenRight = distortion.distort((centerX + halfWidth) / centerZ); 6523 var screenBottom = distortion.distort((centerY - halfHeight) / centerZ); 6524 var result = new Float32Array(4); 6525 result[0] = Math.max(fovLeft, screenLeft); 6526 result[1] = Math.min(fovTop, screenTop); 6527 result[2] = Math.min(fovRight, screenRight); 6528 result[3] = Math.max(fovBottom, screenBottom); 6529 return result; 6530 }; 6531 DeviceInfo.prototype.getLeftEyeNoLensTanAngles = function () { 6532 var viewer = this.viewer; 6533 var device = this.device; 6534 var distortion = this.distortion; 6535 var result = new Float32Array(4); 6536 var fovLeft = distortion.distortInverse(Math.tan(-degToRad * viewer.fov)); 6537 var fovTop = distortion.distortInverse(Math.tan(degToRad * viewer.fov)); 6538 var fovRight = distortion.distortInverse(Math.tan(degToRad * viewer.fov)); 6539 var fovBottom = distortion.distortInverse(Math.tan(-degToRad * viewer.fov)); 6540 var halfWidth = device.widthMeters / 4; 6541 var halfHeight = device.heightMeters / 2; 6542 var verticalLensOffset = viewer.baselineLensDistance - device.bevelMeters - halfHeight; 6543 var centerX = viewer.interLensDistance / 2 - halfWidth; 6544 var centerY = -verticalLensOffset; 6545 var centerZ = viewer.screenLensDistance; 6546 var screenLeft = (centerX - halfWidth) / centerZ; 6547 var screenTop = (centerY + halfHeight) / centerZ; 6548 var screenRight = (centerX + halfWidth) / centerZ; 6549 var screenBottom = (centerY - halfHeight) / centerZ; 6550 result[0] = Math.max(fovLeft, screenLeft); 6551 result[1] = Math.min(fovTop, screenTop); 6552 result[2] = Math.min(fovRight, screenRight); 6553 result[3] = Math.max(fovBottom, screenBottom); 6554 return result; 6555 }; 6556 DeviceInfo.prototype.getLeftEyeVisibleScreenRect = function (undistortedFrustum) { 6557 var viewer = this.viewer; 6558 var device = this.device; 6559 var dist = viewer.screenLensDistance; 6560 var eyeX = (device.widthMeters - viewer.interLensDistance) / 2; 6561 var eyeY = viewer.baselineLensDistance - device.bevelMeters; 6562 var left = (undistortedFrustum[0] * dist + eyeX) / device.widthMeters; 6563 var top = (undistortedFrustum[1] * dist + eyeY) / device.heightMeters; 6564 var right = (undistortedFrustum[2] * dist + eyeX) / device.widthMeters; 6565 var bottom = (undistortedFrustum[3] * dist + eyeY) / device.heightMeters; 6566 return { 6567 x: left, 6568 y: bottom, 6569 width: right - left, 6570 height: top - bottom 6571 }; 6572 }; 6573 DeviceInfo.prototype.getFieldOfViewLeftEye = function (opt_isUndistorted) { 6574 return opt_isUndistorted ? this.getUndistortedFieldOfViewLeftEye() : this.getDistortedFieldOfViewLeftEye(); 6575 }; 6576 DeviceInfo.prototype.getFieldOfViewRightEye = function (opt_isUndistorted) { 6577 var fov = this.getFieldOfViewLeftEye(opt_isUndistorted); 6578 return { 6579 leftDegrees: fov.rightDegrees, 6580 rightDegrees: fov.leftDegrees, 6581 upDegrees: fov.upDegrees, 6582 downDegrees: fov.downDegrees 6583 }; 6584 }; 6585 DeviceInfo.prototype.getUndistortedFieldOfViewLeftEye = function () { 6586 var p = this.getUndistortedParams_(); 6587 return { 6588 leftDegrees: radToDeg * Math.atan(p.outerDist), 6589 rightDegrees: radToDeg * Math.atan(p.innerDist), 6590 downDegrees: radToDeg * Math.atan(p.bottomDist), 6591 upDegrees: radToDeg * Math.atan(p.topDist) 6592 }; 6593 }; 6594 DeviceInfo.prototype.getUndistortedViewportLeftEye = function () { 6595 var p = this.getUndistortedParams_(); 6596 var viewer = this.viewer; 6597 var device = this.device; 6598 var eyeToScreenDistance = viewer.screenLensDistance; 6599 var screenWidth = device.widthMeters / eyeToScreenDistance; 6600 var screenHeight = device.heightMeters / eyeToScreenDistance; 6601 var xPxPerTanAngle = device.width / screenWidth; 6602 var yPxPerTanAngle = device.height / screenHeight; 6603 var x = Math.round((p.eyePosX - p.outerDist) * xPxPerTanAngle); 6604 var y = Math.round((p.eyePosY - p.bottomDist) * yPxPerTanAngle); 6605 return { 6606 x: x, 6607 y: y, 6608 width: Math.round((p.eyePosX + p.innerDist) * xPxPerTanAngle) - x, 6609 height: Math.round((p.eyePosY + p.topDist) * yPxPerTanAngle) - y 6610 }; 6611 }; 6612 DeviceInfo.prototype.getUndistortedParams_ = function () { 6613 var viewer = this.viewer; 6614 var device = this.device; 6615 var distortion = this.distortion; 6616 var eyeToScreenDistance = viewer.screenLensDistance; 6617 var halfLensDistance = viewer.interLensDistance / 2 / eyeToScreenDistance; 6618 var screenWidth = device.widthMeters / eyeToScreenDistance; 6619 var screenHeight = device.heightMeters / eyeToScreenDistance; 6620 var eyePosX = screenWidth / 2 - halfLensDistance; 6621 var eyePosY = (viewer.baselineLensDistance - device.bevelMeters) / eyeToScreenDistance; 6622 var maxFov = viewer.fov; 6623 var viewerMax = distortion.distortInverse(Math.tan(degToRad * maxFov)); 6624 var outerDist = Math.min(eyePosX, viewerMax); 6625 var innerDist = Math.min(halfLensDistance, viewerMax); 6626 var bottomDist = Math.min(eyePosY, viewerMax); 6627 var topDist = Math.min(screenHeight - eyePosY, viewerMax); 6628 return { 6629 outerDist: outerDist, 6630 innerDist: innerDist, 6631 topDist: topDist, 6632 bottomDist: bottomDist, 6633 eyePosX: eyePosX, 6634 eyePosY: eyePosY 6635 }; 6636 }; 6637 function CardboardViewer(params) { 6638 this.id = params.id; 6639 this.label = params.label; 6640 this.fov = params.fov; 6641 this.interLensDistance = params.interLensDistance; 6642 this.baselineLensDistance = params.baselineLensDistance; 6643 this.screenLensDistance = params.screenLensDistance; 6644 this.distortionCoefficients = params.distortionCoefficients; 6645 this.inverseCoefficients = params.inverseCoefficients; 6646 } 6647 DeviceInfo.Viewers = Viewers; 6648 var format = 1; 6649 var last_updated = "2018-02-20T22:55:10Z"; 6650 var devices = [{"type":"android","rules":[{"mdmh":"asus/*/Nexus 7/*"},{"ua":"Nexus 7"}],"dpi":[320.8,323],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"asus/*/ASUS_Z00AD/*"},{"ua":"ASUS_Z00AD"}],"dpi":[403,404.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Google/*/Pixel XL/*"},{"ua":"Pixel XL"}],"dpi":[537.9,533],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Google/*/Pixel/*"},{"ua":"Pixel"}
6650],"dpi":[432.6,436.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC6435LVW/*"},{"ua":"HTC6435LVW"}],"dpi":[449.7,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One XL/*"},{"ua":"HTC One XL"}],"dpi":[315.3,314.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"htc/*/Nexus 9/*"},{"ua":"Nexus 9"}],"dpi":289,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One M9/*"},{"ua":"HTC One M9"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One_M8/*"},{"ua":"HTC One_M8"}],"dpi":[449.7,447.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One/*"},{"ua":"HTC One"}],"dpi":472.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Huawei/*/Nexus 6P/*"},{"ua":"Nexus 6P"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LENOVO/*/Lenovo PB2-690Y/*"},{"ua":"Lenovo PB2-690Y"}],"dpi":[457.2,454.713],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5X/*"},{"ua":"Nexus 5X"}],"dpi":[422,419.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS345/*"},{"ua":"LGMS345"}],"dpi":[221.7,219.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D800/*"},{"ua":"LG-D800"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D850/*"},{"ua":"LG-D850"}],"dpi":[537.9,541.9],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/VS985 4G/*"},{"ua":"VS985 4G"}],"dpi":[537.9,535.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5/*"},{"ua":"Nexus 5 B"}],"dpi":[442.4,444.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 4/*"},{"ua":"Nexus 4"}],"dpi":[319.8,318.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LG-P769/*"},{"ua":"LG-P769"}],"dpi":[240.6,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS323/*"},{"ua":"LGMS323"}],"dpi":[206.6,204.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGLS996/*"},{"ua":"LGLS996"}],"dpi":[403.4,401.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/4560MMX/*"},{"ua":"4560MMX"}],"dpi":[240,219.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/A250/*"},{"ua":"Micromax A250"}],"dpi":[480,446.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/Micromax AQ4501/*"},{"ua":"Micromax AQ4501"}],"dpi":240,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/G5/*"},{"ua":"Moto G (5) Plus"}],"dpi":[403.4,403],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/DROID RAZR/*"},{"ua":"DROID RAZR"}],"dpi":[368.1,256.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT830C/*"},{"ua":"XT830C"}],"dpi":[254,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1021/*"},{"ua":"XT1021"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1023/*"},{"ua":"XT1023"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1028/*"},{"ua":"XT1028"}],"dpi":[326.6,327.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1034/*"},{"ua":"XT1034"}],"dpi":[326.6,328.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1053/*"},{"ua":"XT1053"}],"dpi":[315.3,316.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1562/*"},{"ua":"XT1562"}],"dpi":[403.4,402.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/Nexus 6/*"},{"ua":"Nexus 6 B"}],"dpi":[494.3,489.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1063/*"},{"ua":"XT1063"}
6650],"dpi":[295,296.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1064/*"},{"ua":"XT1064"}],"dpi":[295,295.6],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1092/*"},{"ua":"XT1092"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1095/*"},{"ua":"XT1095"}],"dpi":[422,423.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/G4/*"},{"ua":"Moto G (4)"}],"dpi":401,"bw":4,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/A0001/*"},{"ua":"A0001"}],"dpi":[403.4,401],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE E1005/*"},{"ua":"ONE E1005"}],"dpi":[442.4,441.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE A2005/*"},{"ua":"ONE A2005"}],"dpi":[391.9,405.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONEPLUS A5000/*"},{"ua":"ONEPLUS A5000 "}],"dpi":[403.411,399.737],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE A5010/*"},{"ua":"ONEPLUS A5010"}],"dpi":[403,400],"bw":2,"ac":1000},{"type":"android","rules":[{"mdmh":"OPPO/*/X909/*"},{"ua":"X909"}],"dpi":[442.4,444.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9082/*"},{"ua":"GT-I9082"}],"dpi":[184.7,185.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G360P/*"},{"ua":"SM-G360P"}],"dpi":[196.7,205.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Nexus S/*"},{"ua":"Nexus S"}],"dpi":[234.5,229.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[304.8,303.9],"bw":5,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T230NU/*"},{"ua":"SM-T230NU"}],"dpi":216,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SGH-T399/*"},{"ua":"SGH-T399"}],"dpi":[217.7,231.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SGH-M919/*"},{"ua":"SGH-M919"}],"dpi":[440.8,437.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N9005/*"},{"ua":"SM-N9005"}],"dpi":[386.4,387],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SM-N900A/*"},{"ua":"SAMSUNG-SM-N900A"}],"dpi":[386.4,387.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9500/*"},{"ua":"GT-I9500"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9505/*"},{"ua":"GT-I9505"}],"dpi":439.4,"bw":4,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900F/*"},{"ua":"SM-G900F"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900M/*"},{"ua":"SM-G900M"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G800F/*"},{"ua":"SM-G800F"}],"dpi":326.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G906S/*"},{"ua":"SM-G906S"}],"dpi":[562.7,572.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[306.7,304.8],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T535/*"},{"ua":"SM-T535"}],"dpi":[142.6,136.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920C/*"},{"ua":"SM-N920C"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920P/*"},{"ua":"SM-N920P"}],"dpi":[386.3655,390.144],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920W8/*"},{"ua":"SM-N920W8"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300I/*"},{"ua":"GT-I9300I"}],"dpi":[304.8,305.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9195/*"},{"ua":"GT-I9195"}],"dpi":[249.4,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-L520/*"},{"ua":"SPH-L520"}],"dpi":[249.4,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SGH-I717/*"},{"ua":"SAMSUNG-SGH-I717"}],"dpi":285.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-D710/*"},{"ua":"SPH-D710"}],"dpi":[217.7,204.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-N7100/*"},{"ua":"GT-N7100"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SCH-I605/*"},{"ua":"SCH-I605"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Galaxy Nexus/*"},{"ua":"Galaxy Nexus"}],"dpi":[315.3,314.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910H/*"},{"ua":"SM-N910H"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910C/*"},{"ua":"SM-N910C"}],"dpi":[515.2,520.2],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G130M/*"},{"ua":"SM-G130M"}],"dpi":[165.9,164.8],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G928I/*"},{"ua":"SM-G928I"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920F/*"},{"ua":"SM-G920F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920P/*"},{"ua":"SM-G920P"}],"dpi":[522.5,577],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925F/*"},{"ua":"SM-G925F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925V/*"},{"ua":"SM-G925V"}],"dpi":[522.5,576.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G930F/*"},{"ua":"SM-G930F"}],"dpi":576.6,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G935F/*"},{"ua":"SM-G935F"}],"dpi":533,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G950F/*"},{"ua":"SM-G950F"}],"dpi":[562.707,565.293],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G955U/*"},{"ua":"SM-G955U"}],"dpi":[522.514,525.762],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"Sony/*/C6903/*"},{"ua":"C6903"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"Sony/*/D6653/*"},{"ua":"D6653"}],"dpi":[428.6,427.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6653/*"},{"ua":"E6653"}],"dpi":[428.6,425.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6853/*"},{"ua":"E6853"}],"dpi":[403.4,401.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/SGP321/*"},{"ua":"SGP321"}],"dpi":[224.7,224.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"TCT/*/ALCATEL ONE TOUCH Fierce/*"},{"ua":"ALCATEL ONE TOUCH Fierce"}],"dpi":[240,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"THL/*/thl 5000/*"},{"ua":"thl 5000"}],"dpi":[480,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Fly/*/IQ4412/*"},{"ua":"IQ4412"}],"dpi":307.9,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"ZTE/*/ZTE Blade L2/*"},{"ua":"ZTE Blade L2"}],"dpi":240,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"BENEVE/*/VR518/*"},{"ua":"VR518"}],"dpi":480,"bw":3,"ac":500}
vendor: 9,300 bytes, lines 6650-6900
6650,{"type":"ios","rules":[{"res":[640,960]}],"dpi":[325.1,328.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[640,1136]}],"dpi":[317.1,320.2],"bw":3,"ac":1000},{"type":"ios","rules":[{"res":[750,1334]}],"dpi":326.4,"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1242,2208]}],"dpi":[453.6,458.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1125,2001]}],"dpi":[410.9,415.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1125,2436]}],"dpi":458,"bw":4,"ac":1000}]; 6651 var DPDB_CACHE = { 6652 format: format, 6653 last_updated: last_updated, 6654 devices: devices 6655 }; 6656 function Dpdb(url, onDeviceParamsUpdated) { 6657 this.dpdb = DPDB_CACHE; 6658 this.recalculateDeviceParams_(); 6659 if (url) { 6660 this.onDeviceParamsUpdated = onDeviceParamsUpdated; 6661 var xhr = new XMLHttpRequest(); 6662 var obj = this; 6663 xhr.open('GET', url, true); 6664 xhr.addEventListener('load', function () { 6665 obj.loading = false; 6666 if (xhr.status >= 200 && xhr.status <= 299) { 6667 obj.dpdb = JSON.parse(xhr.response); 6668 obj.recalculateDeviceParams_(); 6669 } else { 6670 console.error('Error loading online DPDB!'); 6671 } 6672 }); 6673 xhr.send(); 6674 } 6675 } 6676 Dpdb.prototype.getDeviceParams = function () { 6677 return this.deviceParams; 6678 }; 6679 Dpdb.prototype.recalculateDeviceParams_ = function () { 6680 var newDeviceParams = this.calcDeviceParams_(); 6681 if (newDeviceParams) { 6682 this.deviceParams = newDeviceParams; 6683 if (this.onDeviceParamsUpdated) { 6684 this.onDeviceParamsUpdated(this.deviceParams); 6685 } 6686 } else { 6687 console.error('Failed to recalculate device parameters.'); 6688 } 6689 }; 6690 Dpdb.prototype.calcDeviceParams_ = function () { 6691 var db = this.dpdb; 6692 if (!db) { 6693 console.error('DPDB not available.'); 6694 return null; 6695 } 6696 if (db.format != 1) { 6697 console.error('DPDB has unexpected format version.'); 6698 return null; 6699 } 6700 if (!db.devices || !db.devices.length) { 6701 console.error('DPDB does not have a devices section.'); 6702 return null; 6703 } 6704 var userAgent = navigator.userAgent || navigator.vendor || window.opera; 6705 var width = getScreenWidth(); 6706 var height = getScreenHeight(); 6707 if (!db.devices) { 6708 console.error('DPDB has no devices section.'); 6709 return null; 6710 } 6711 for (var i = 0; i < db.devices.length; i++) { 6712 var device = db.devices[i]; 6713 if (!device.rules) { 6714 console.warn('Device[' + i + '] has no rules section.'); 6715 continue; 6716 } 6717 if (device.type != 'ios' && device.type != 'android') { 6718 console.warn('Device[' + i + '] has invalid type.'); 6719 continue; 6720 } 6721 if (isIOS() != (device.type == 'ios')) continue; 6722 var matched = false; 6723 for (var j = 0; j < device.rules.length; j++) { 6724 var rule = device.rules[j]; 6725 if (this.matchRule_(rule, userAgent, width, height)) { 6726 matched = true; 6727 break; 6728 } 6729 } 6730 if (!matched) continue; 6731 var xdpi = device.dpi[0] || device.dpi; 6732 var ydpi = device.dpi[1] || device.dpi; 6733 return new DeviceParams({ xdpi: xdpi, ydpi: ydpi, bevelMm: device.bw }); 6734 } 6735 console.warn('No DPDB device match.'); 6736 return null; 6737 }; 6738 Dpdb.prototype.matchRule_ = function (rule, ua, screenWidth, screenHeight) { 6739 if (!rule.ua && !rule.res) return false; 6740 if (rule.ua && ua.indexOf(rule.ua) < 0) return false; 6741 if (rule.res) { 6742 if (!rule.res[0] || !rule.res[1]) return false; 6743 var resX = rule.res[0]; 6744 var resY = rule.res[1]; 6745 if (Math.min(screenWidth, screenHeight) != Math.min(resX, resY) || Math.max(screenWidth, screenHeight) != Math.max(resX, resY)) { 6746 return false; 6747 } 6748 } 6749 return true; 6750 }; 6751 function DeviceParams(params) { 6752 this.xdpi = params.xdpi; 6753 this.ydpi = params.ydpi; 6754 this.bevelMm = params.bevelMm; 6755 } 6756 function SensorSample(sample, timestampS) { 6757 this.set(sample, timestampS); 6758 } 6759 SensorSample.prototype.set = function (sample, timestampS) { 6760 this.sample = sample; 6761 this.timestampS = timestampS; 6762 }; 6763 SensorSample.prototype.copy = function (sensorSample) { 6764 this.set(sensorSample.sample, sensorSample.timestampS); 6765 }; 6766 function ComplementaryFilter(kFilter, isDebug) { 6767 this.kFilter = kFilter; 6768 this.isDebug = isDebug; 6769 this.currentAccelMeasurement = new SensorSample(); 6770 this.currentGyroMeasurement = new SensorSample(); 6771 this.previousGyroMeasurement = new SensorSample(); 6772 if (isIOS()) { 6773 this.filterQ = new Quaternion(-1, 0, 0, 1); 6774 } else { 6775 this.filterQ = new Quaternion(1, 0, 0, 1); 6776 } 6777 this.previousFilterQ = new Quaternion(); 6778 this.previousFilterQ.copy(this.filterQ); 6779 this.accelQ = new Quaternion(); 6780 this.isOrientationInitialized = false; 6781 this.estimatedGravity = new Vector3(); 6782 this.measuredGravity = new Vector3(); 6783 this.gyroIntegralQ = new Quaternion(); 6784 } 6785 ComplementaryFilter.prototype.addAccelMeasurement = function (vector, timestampS) { 6786 this.currentAccelMeasurement.set(vector, timestampS); 6787 }; 6788 ComplementaryFilter.prototype.addGyroMeasurement = function (vector, timestampS) { 6789 this.currentGyroMeasurement.set(vector, timestampS); 6790 var deltaT = timestampS - this.previousGyroMeasurement.timestampS; 6791 if (isTimestampDeltaValid(deltaT)) { 6792 this.run_(); 6793 } 6794 this.previousGyroMeasurement.copy(this.currentGyroMeasurement); 6795 }; 6796 ComplementaryFilter.prototype.run_ = function () { 6797 if (!this.isOrientationInitialized) { 6798 this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); 6799 this.previousFilterQ.copy(this.accelQ); 6800 this.isOrientationInitialized = true; 6801 return; 6802 } 6803 var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; 6804 var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); 6805 this.gyroIntegralQ.multiply(gyroDeltaQ); 6806 this.filterQ.copy(this.previousFilterQ); 6807 this.filterQ.multiply(gyroDeltaQ); 6808 var invFilterQ = new Quaternion(); 6809 invFilterQ.copy(this.filterQ); 6810 invFilterQ.inverse(); 6811 this.estimatedGravity.set(0, 0, -1); 6812 this.estimatedGravity.applyQuaternion(invFilterQ); 6813 this.estimatedGravity.normalize(); 6814 this.measuredGravity.copy(this.currentAccelMeasurement.sample); 6815 this.measuredGravity.normalize(); 6816 var deltaQ = new Quaternion(); 6817 deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); 6818 deltaQ.inverse(); 6819 if (this.isDebug) { 6820 console.log('Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)', radToDeg * getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); 6821 } 6822 var targetQ = new Quaternion(); 6823 targetQ.copy(this.filterQ); 6824 targetQ.multiply(deltaQ); 6825 this.filterQ.slerp(targetQ, 1 - this.kFilter); 6826 this.previousFilterQ.copy(this.filterQ); 6827 }; 6828 ComplementaryFilter.prototype.getOrientation = function () { 6829 return this.filterQ; 6830 }; 6831 ComplementaryFilter.prototype.accelToQuaternion_ = function (accel) { 6832 var normAccel = new Vector3(); 6833 normAccel.copy(accel); 6834 normAccel.normalize(); 6835 var quat = new Quaternion(); 6836 quat.setFromUnitVectors(new Vector3(0, 0, -1), normAccel); 6837 quat.inverse(); 6838 return quat; 6839 }; 6840 ComplementaryFilter.prototype.gyroToQuaternionDelta_ = function (gyro, dt) { 6841 var quat = new Quaternion(); 6842 var axis = new Vector3(); 6843 axis.copy(gyro); 6844 axis.normalize(); 6845 quat.setFromAxisAngle(axis, gyro.length() * dt); 6846 return quat; 6847 }; 6848 function PosePredictor(predictionTimeS, isDebug) { 6849 this.predictionTimeS = predictionTimeS; 6850 this.isDebug = isDebug; 6851 this.previousQ = new Quaternion(); 6852 this.previousTimestampS = null; 6853 this.deltaQ = new Quaternion(); 6854 this.outQ = new Quaternion(); 6855 } 6856 PosePredictor.prototype.getPrediction = function (currentQ, gyro, timestampS) { 6857 if (!this.previousTimestampS) { 6858 this.previousQ.copy(currentQ); 6859 this.previousTimestampS = timestampS; 6860 return currentQ; 6861 } 6862 var axis = new Vector3(); 6863 axis.copy(gyro); 6864 axis.normalize(); 6865 var angularSpeed = gyro.length(); 6866 if (angularSpeed < degToRad * 20) { 6867 if (this.isDebug) { 6868 console.log('Moving slowly, at %s deg/s: no prediction', (radToDeg * angularSpeed).toFixed(1)); 6869 } 6870 this.outQ.copy(currentQ); 6871 this.previousQ.copy(currentQ); 6872 return this.outQ; 6873 } 6874 var predictAngle = angularSpeed * this.predictionTimeS; 6875 this.deltaQ.setFromAxisAngle(axis, predictAngle); 6876 this.outQ.copy(this.previousQ); 6877 this.outQ.multiply(this.deltaQ); 6878 this.previousQ.copy(currentQ); 6879 this.previousTimestampS = timestampS; 6880 return this.outQ; 6881 }; 6882 function FusionPoseSensor(kFilter, predictionTime, yawOnly, isDebug) { 6883 this.yawOnly = yawOnly; 6884 this.accelerometer = new Vector3(); 6885 this.gyroscope = new Vector3(); 6886 this.filter = new ComplementaryFilter(kFilter, isDebug); 6887 this.posePredictor = new PosePredictor(predictionTime, isDebug); 6888 this.isFirefoxAndroid = isFirefoxAndroid(); 6889 this.isIOS = isIOS(); 6890 var chromeVersion = getChromeVersion(); 6891 this.isDeviceMotionInRadians = !this.isIOS && chromeVersion && chromeVersion < 66; 6892 this.isWithoutDeviceMotion = isChromeWithoutDeviceMotion(); 6893 this.filterToWorldQ = new Quaternion(); 6894 if (isIOS()) { 6895 this.filterToWorldQ.setFromAxisAngle(new Vector3(1, 0, 0), Math.PI / 2); 6896 } else { 6897 this.filterToWorldQ.setFromAxisAngle(new Vector3(1, 0, 0), -Math.PI / 2); 6898 } 6899 this.inverseWorldToScreenQ = new Quaternion(); 6900 this.worldToScreenQ = new Quaternion();
vendor: 7,633 bytes, lines 6901-7107
6901 this.originalPoseAdjustQ = new Quaternion(); 6902 this.originalPoseAdjustQ.setFromAxisAngle(new Vector3(0, 0, 1), -window.orientation * Math.PI / 180); 6903 this.setScreenTransform_(); 6904 if (isLandscapeMode()) { 6905 this.filterToWorldQ.multiply(this.inverseWorldToScreenQ); 6906 } 6907 this.resetQ = new Quaternion(); 6908 this.orientationOut_ = new Float32Array(4); 6909 this.start(); 6910 } 6911 FusionPoseSensor.prototype.getPosition = function () { 6912 return null; 6913 }; 6914 FusionPoseSensor.prototype.getOrientation = function () { 6915 var orientation = void 0; 6916 if (this.isWithoutDeviceMotion && this._deviceOrientationQ) { 6917 this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { 6918 var z = new Quaternion().setFromAxisAngle(new Vector3(0, 0, -1), 0); 6919 var y = new Quaternion(); 6920 if (window.orientation === -90) { 6921 y.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI / -2); 6922 } else { 6923 y.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI / 2); 6924 } 6925 return z.multiply(y); 6926 }(); 6927 this.deviceOrientationFilterToWorldQ = this.deviceOrientationFilterToWorldQ || function () { 6928 var q = new Quaternion(); 6929 q.setFromAxisAngle(new Vector3(1, 0, 0), -Math.PI / 2); 6930 return q; 6931 }(); 6932 orientation = this._deviceOrientationQ; 6933 var out = new Quaternion(); 6934 out.copy(orientation); 6935 out.multiply(this.deviceOrientationFilterToWorldQ); 6936 out.multiply(this.resetQ); 6937 out.multiply(this.worldToScreenQ); 6938 out.multiplyQuaternions(this.deviceOrientationFixQ, out); 6939 if (this.yawOnly) { 6940 out.x = 0; 6941 out.z = 0; 6942 out.normalize(); 6943 } 6944 this.orientationOut_[0] = out.x; 6945 this.orientationOut_[1] = out.y; 6946 this.orientationOut_[2] = out.z; 6947 this.orientationOut_[3] = out.w; 6948 return this.orientationOut_; 6949 } else { 6950 var filterOrientation = this.filter.getOrientation(); 6951 orientation = this.posePredictor.getPrediction(filterOrientation, this.gyroscope, this.previousTimestampS); 6952 } 6953 var out = new Quaternion(); 6954 out.copy(this.filterToWorldQ); 6955 out.multiply(this.resetQ); 6956 out.multiply(orientation); 6957 out.multiply(this.worldToScreenQ); 6958 if (this.yawOnly) { 6959 out.x = 0; 6960 out.z = 0; 6961 out.normalize(); 6962 } 6963 this.orientationOut_[0] = out.x; 6964 this.orientationOut_[1] = out.y; 6965 this.orientationOut_[2] = out.z; 6966 this.orientationOut_[3] = out.w; 6967 return this.orientationOut_; 6968 }; 6969 FusionPoseSensor.prototype.resetPose = function () { 6970 this.resetQ.copy(this.filter.getOrientation()); 6971 this.resetQ.x = 0; 6972 this.resetQ.y = 0; 6973 this.resetQ.z *= -1; 6974 this.resetQ.normalize(); 6975 if (isLandscapeMode()) { 6976 this.resetQ.multiply(this.inverseWorldToScreenQ); 6977 } 6978 this.resetQ.multiply(this.originalPoseAdjustQ); 6979 }; 6980 FusionPoseSensor.prototype.onDeviceOrientation_ = function (e) { 6981 this._deviceOrientationQ = this._deviceOrientationQ || new Quaternion(); 6982 var alpha = e.alpha, 6983 beta = e.beta, 6984 gamma = e.gamma; 6985 alpha = (alpha || 0) * Math.PI / 180; 6986 beta = (beta || 0) * Math.PI / 180; 6987 gamma = (gamma || 0) * Math.PI / 180; 6988 this._deviceOrientationQ.setFromEulerYXZ(beta, alpha, -gamma); 6989 }; 6990 FusionPoseSensor.prototype.onDeviceMotion_ = function (deviceMotion) { 6991 this.updateDeviceMotion_(deviceMotion); 6992 }; 6993 FusionPoseSensor.prototype.updateDeviceMotion_ = function (deviceMotion) { 6994 var accGravity = deviceMotion.accelerationIncludingGravity; 6995 var rotRate = deviceMotion.rotationRate; 6996 var timestampS = deviceMotion.timeStamp / 1000; 6997 var deltaS = timestampS - this.previousTimestampS; 6998 if (deltaS < 0) { 6999 warnOnce('fusion-pose-sensor:invalid:non-monotonic', 'Invalid timestamps detected: non-monotonic timestamp from devicemotion'); 7000 this.previousTimestampS = timestampS; 7001 return; 7002 } else if (deltaS <= MIN_TIMESTEP || deltaS > MAX_TIMESTEP) { 7003 warnOnce('fusion-pose-sensor:invalid:outside-threshold', 'Invalid timestamps detected: Timestamp from devicemotion outside expected range.'); 7004 this.previousTimestampS = timestampS; 7005 return; 7006 } 7007 this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); 7008 if (isR7()) { 7009 this.gyroscope.set(-rotRate.beta, rotRate.alpha, rotRate.gamma); 7010 } else { 7011 this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); 7012 } 7013 if (!this.isDeviceMotionInRadians) { 7014 this.gyroscope.multiplyScalar(Math.PI / 180); 7015 } 7016 this.filter.addAccelMeasurement(this.accelerometer, timestampS); 7017 this.filter.addGyroMeasurement(this.gyroscope, timestampS); 7018 this.previousTimestampS = timestampS; 7019 }; 7020 FusionPoseSensor.prototype.onOrientationChange_ = function (screenOrientation) { 7021 this.setScreenTransform_(); 7022 }; 7023 FusionPoseSensor.prototype.onMessage_ = function (event) { 7024 var message = event.data; 7025 if (!message || !message.type) { 7026 return; 7027 } 7028 var type = message.type.toLowerCase(); 7029 if (type !== 'devicemotion') { 7030 return; 7031 } 7032 this.updateDeviceMotion_(message.deviceMotionEvent); 7033 }; 7034 FusionPoseSensor.prototype.setScreenTransform_ = function () { 7035 this.worldToScreenQ.set(0, 0, 0, 1); 7036 switch (window.orientation) { 7037 case 0: 7038 break; 7039 case 90: 7040 this.worldToScreenQ.setFromAxisAngle(new Vector3(0, 0, 1), -Math.PI / 2); 7041 break; 7042 case -90: 7043 this.worldToScreenQ.setFromAxisAngle(new Vector3(0, 0, 1), Math.PI / 2); 7044 break; 7045 } 7046 this.inverseWorldToScreenQ.copy(this.worldToScreenQ); 7047 this.inverseWorldToScreenQ.inverse(); 7048 }; 7049 FusionPoseSensor.prototype.start = function () { 7050 this.onDeviceMotionCallback_ = this.onDeviceMotion_.bind(this); 7051 this.onOrientationChangeCallback_ = this.onOrientationChange_.bind(this); 7052 this.onMessageCallback_ = this.onMessage_.bind(this); 7053 this.onDeviceOrientationCallback_ = this.onDeviceOrientation_.bind(this); 7054 if (isIOS() && isInsideCrossOriginIFrame()) { 7055 window.addEventListener('message', this.onMessageCallback_); 7056 } 7057 window.addEventListener('orientationchange', this.onOrientationChangeCallback_); 7058 if (this.isWithoutDeviceMotion) { 7059 window.addEventListener('deviceorientation', this.onDeviceOrientationCallback_); 7060 } else { 7061 window.addEventListener('devicemotion', this.onDeviceMotionCallback_); 7062 } 7063 }; 7064 FusionPoseSensor.prototype.stop = function () { 7065 window.removeEventListener('devicemotion', this.onDeviceMotionCallback_); 7066 window.removeEventListener('deviceorientation', this.onDeviceOrientationCallback_); 7067 window.removeEventListener('orientationchange', this.onOrientationChangeCallback_); 7068 window.removeEventListener('message', this.onMessageCallback_); 7069 }; 7070 var SENSOR_FREQUENCY = 60; 7071 var X_AXIS = new Vector3(1, 0, 0); 7072 var Z_AXIS = new Vector3(0, 0, 1); 7073 var orientation = {}; 7074 if (screen.orientation) { 7075 orientation = screen.orientation; 7076 } else if (screen.msOrientation) { 7077 orientation = screen.msOrientation; 7078 } else { 7079 Object.defineProperty(orientation, 'angle', { 7080 get: function get$$1() { 7081 return window.orientation || 0; 7082 } 7083 }); 7084 } 7085 var SENSOR_TO_VR = new Quaternion(); 7086 SENSOR_TO_VR.setFromAxisAngle(X_AXIS, -Math.PI / 2); 7087 SENSOR_TO_VR.multiply(new Quaternion().setFromAxisAngle(Z_AXIS, Math.PI / 2)); 7088 var PoseSensor = function () { 7089 function PoseSensor(config) { 7090 classCallCheck(this, PoseSensor); 7091 this.config = config; 7092 this.sensor = null; 7093 this.fusionSensor = null; 7094 this._out = new Float32Array(4); 7095 this.api = null; 7096 this.errors = []; 7097 this._sensorQ = new Quaternion(); 7098 this._worldToScreenQ = new Quaternion(); 7099 this._outQ = new Quaternion(); 7100 this._onSensorRead = this._onSensorRead.bind(this); 7101 this._onSensorError = this._onSensorError.bind(this); 7102 this._onOrientationChange = this._onOrientationChange.bind(this); 7103 this._onOrientationChange(); 7104 this.init(); 7105 } 7106 createClass(PoseSensor, [{ 7107 key: 'init',
vendor: 5,556 bytes, lines 7108-7196
7108 value: function init() { 7109 var sensor = null; 7110 try { 7111 sensor = new RelativeOrientationSensor({ frequency: SENSOR_FREQUENCY }); 7112 sensor.addEventListener('error', this._onSensorError); 7113 } catch (error) { 7114 this.errors.push(error); 7115 if (error.name === 'SecurityError') { 7116 console.error('Cannot construct sensors due to the Feature Policy'); 7117 console.warn('Attempting to fall back using "devicemotion"; however this will ' + 'fail in the future without correct permissions.'); 7118 this.useDeviceMotion(); 7119 } else if (error.name === 'ReferenceError') { 7120 this.useDeviceMotion(); 7121 } else { 7122 console.error(error); 7123 } 7124 } 7125 if (sensor) { 7126 this.api = 'sensor'; 7127 this.sensor = sensor; 7128 this.sensor.addEventListener('reading', this._onSensorRead); 7129 this.sensor.start(); 7130 } 7131 window.addEventListener('orientationchange', this._onOrientationChange); 7132 } 7133 }, { 7134 key: 'useDeviceMotion', 7135 value: function useDeviceMotion() { 7136 this.api = 'devicemotion'; 7137 this.fusionSensor = new FusionPoseSensor(this.config.K_FILTER, this.config.PREDICTION_TIME_S, this.config.YAW_ONLY, this.config.DEBUG); 7138 if (this.sensor) { 7139 this.sensor.removeEventListener('reading', this._onSensorRead); 7140 this.sensor.removeEventListener('error', this._onSensorError); 7141 this.sensor = null; 7142 } 7143 } 7144 }, { 7145 key: 'getOrientation', 7146 value: function getOrientation() { 7147 if (this.fusionSensor) { 7148 return this.fusionSensor.getOrientation(); 7149 } 7150 if (!this.sensor || !this.sensor.quaternion) { 7151 this._out[0] = this._out[1] = this._out[2] = 0; 7152 this._out[3] = 1; 7153 return this._out; 7154 } 7155 var q = this.sensor.quaternion; 7156 this._sensorQ.set(q[0], q[1], q[2], q[3]); 7157 var out = this._outQ; 7158 out.copy(SENSOR_TO_VR); 7159 out.multiply(this._sensorQ); 7160 out.multiply(this._worldToScreenQ); 7161 if (this.config.YAW_ONLY) { 7162 out.x = out.z = 0; 7163 out.normalize(); 7164 } 7165 this._out[0] = out.x; 7166 this._out[1] = out.y; 7167 this._out[2] = out.z; 7168 this._out[3] = out.w; 7169 return this._out; 7170 } 7171 }, { 7172 key: '_onSensorError', 7173 value: function _onSensorError(event) { 7174 this.errors.push(event.error); 7175 if (event.error.name === 'NotAllowedError') { 7176 console.error('Permission to access sensor was denied'); 7177 } else if (event.error.name === 'NotReadableError') { 7178 console.error('Sensor could not be read'); 7179 } else { 7180 console.error(event.error); 7181 } 7182 this.useDeviceMotion(); 7183 } 7184 }, { 7185 key: '_onSensorRead', 7186 value: function _onSensorRead() {} 7187 }, { 7188 key: '_onOrientationChange', 7189 value: function _onOrientationChange() { 7190 var angle = -orientation.angle * Math.PI / 180; 7191 this._worldToScreenQ.setFromAxisAngle(Z_AXIS, angle); 7192 } 7193 }]); 7194 return PoseSensor; 7195 }(); 7196 var rotateInstructionsAsset = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjE5OHB4IiBoZWlnaHQ9IjI0MHB4IiB2aWV3Qm94PSIwIDAgMTk4IDI0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpza2V0Y2g9Imh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaC9ucyI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDMuMy4zICgxMjA4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+dHJhbnNpdGlvbjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPgogICAgICAgIDxnIGlkPSJ0cmFuc2l0aW9uIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIj4KICAgICAgICAgICAgPGcgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTQtKy1JbXBvcnRlZC1MYXllcnMtQ29weS0rLUltcG9ydGVkLUxheWVycy1Db3B5LTItQ29weSIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHktNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDEwNy4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjYyNSwyLjUyNyBDMTQ5LjYyNSwyLjUyNyAxNTUuODA1LDYuMDk2IDE1Ni4zNjIsNi40MTggTDE1Ni4zNjIsNy4zMDQgQzE1Ni4zNjIsNy40ODEgMTU2LjM3NSw3LjY2NCAxNTYuNCw3Ljg1MyBDMTU2LjQxLDcuOTM0IDE1Ni40Miw4LjAxNSAxNTYuNDI3LDguMDk1IEMxNTYuNTY3LDkuNTEgMTU3LjQwMSwxMS4wOTMgMTU4LjUzMiwxMi4wOTQgTDE2NC4yNTIsMTcuMTU2IEwxNjQuMzMzLDE3LjA2NiBDMTY0LjMzMywxNy4wNjYgMTY4LjcxNSwxNC41MzYgMTY5LjU2OCwxNC4wNDIgQzE3MS4wMjUsMTQuODgzIDE5NS41MzgsMjkuMDM1IDE5NS41MzgsMjkuMDM1IEwxOTUuNTM4LDgzLjAzNiBDMTk1LjUzOCw4My44MDcgMTk1LjE1Miw4NC4yNTMgMTk0LjU5LDg0LjI1MyBDMTk0LjM1Nyw4NC4yNTMgMTk0LjA5NSw4NC4xNzcgMTkzLjgxOCw4NC4wMTcgTDE2OS44NTEsNzAuMTc5IEwxNjkuODM3LDcwLjIwMyBMMTQyLjUxNSw4NS45NzggTDE0MS42NjUsODQuNjU1IEMxMzYuOTM0LDgzLjEyNiAxMzEuOTE3LDgxLjkxNSAxMjYuNzE0LDgxLjA0NSBDMTI2LjcwOSw4MS4wNiAxMjYuNzA3LDgxLjA2OSAxMjYuNzA3LDgxLjA2OSBMMTIxLjY0LDk4LjAzIEwxMTMuNzQ5LDEwMi41ODYgTDExMy43MTIsMTAyLjUyMyBMMTEzLjcxMiwxMzAuMTEzIEMxMTMuNzEyLDEzMC44ODUgMTEzLjMyNiwxMzEuMzMgMTEyLjc2NCwxMzEuMzMgQzExMi41MzIsMTMxLjMzIDExMi4yNjksMTMxLjI1NCAxMTEuOTkyLDEzMS4wOTQgTDY5LjUxOSwxMDYuNTcyIEM2OC41NjksMTA2LjAyMyA2Ny43OTksMTA0LjY5NSA2Ny43OTksMTAzLjYwNSBMNjcuNzk5LDEwMi41NyBMNjcuNzc4LDEwMi42MTcgQzY3LjI3LDEwMi4zOTMgNjYuNjQ4LDEwMi4yNDkgNjUuOTYyLDEwMi4yMTggQzY1Ljg3NSwxMDIuMjE0IDY1Ljc4OCwxMDIuMjEyIDY1LjcwMSwxMDIuMjEyIEM2NS42MDYsMTAyLjIxMiA2NS41MTEsMTAyLjIxNSA2NS40MTYsMTAyLjIxOSBDNjUuMTk1LDEwMi4yMjkgNjQuOTc0LDEwMi4yMzUgNjQuNzU0LDEwMi4yMzUgQzY0LjMzMSwxMDIuMjM1IDYzLjkxMSwxMDIuMjE2IDYzLjQ5OCwxMDIuMTc4IEM2MS44NDMsMTAyLjAyNSA2MC4yOTgsMTAxLjU3OCA1OS4wOTQsMTAwLjg4MiBMMTIuNTE4LDczLjk5MiBMMTIuNTIzLDc0LjAwNCBMMi4yNDUsNTUuMjU0IEMxLjI0NCw1My40MjcgMi4wMDQsNTEuMDM4IDMuOTQzLDQ5LjkxOCBMNTkuOTU0LDE3LjU3MyB
7196DNjAuNjI2LDE3LjE4NSA2MS4zNSwxNy4wMDEgNjIuMDUzLDE3LjAwMSBDNjMuMzc5LDE3LjAwMSA2NC42MjUsMTcuNjYgNjUuMjgsMTguODU0IEw2NS4yODUsMTguODUxIEw2NS41MTIsMTkuMjY0IEw2NS41MDYsMTkuMjY4IEM2NS45MDksMjAuMDAzIDY2LjQwNSwyMC42OCA2Ni45ODMsMjEuMjg2IEw2Ny4yNiwyMS41NTYgQzY5LjE3NCwyMy40MDYgNzEuNzI4LDI0LjM1NyA3NC4zNzMsMjQuMzU3IEM3Ni4zMjIsMjQuMzU3IDc4LjMyMSwyMy44NCA4MC4xNDgsMjIuNzg1IEM4MC4xNjEsMjIuNzg1IDg3LjQ2NywxOC41NjYgODcuNDY3LDE4LjU2NiBDODguMTM5LDE4LjE3OCA4OC44NjMsMTcuOTk0IDg5LjU2NiwxNy45OTQgQzkwLjg5MiwxNy45OTQgOTIuMTM4LDE4LjY1MiA5Mi43OTIsMTkuODQ3IEw5Ni4wNDIsMjUuNzc1IEw5Ni4wNjQsMjUuNzU3IEwxMDIuODQ5LDI5LjY3NCBMMTAyLjc0NCwyOS40OTIgTDE0OS42MjUsMi41MjcgTTE0OS42MjUsMC44OTIgQzE0OS4zNDMsMC44OTIgMTQ5LjA2MiwwLjk2NSAxNDguODEsMS4xMSBMMTAyLjY0MSwyNy42NjYgTDk3LjIzMSwyNC41NDIgTDk0LjIyNiwxOS4wNjEgQzkzLjMxMywxNy4zOTQgOTEuNTI3LDE2LjM1OSA4OS41NjYsMTYuMzU4IEM4OC41NTUsMTYuMzU4IDg3LjU0NiwxNi42MzIgODYuNjQ5LDE3LjE1IEM4My44NzgsMTguNzUgNzkuNjg3LDIxLjE2OSA3OS4zNzQsMjEuMzQ1IEM3OS4zNTksMjEuMzUzIDc5LjM0NSwyMS4zNjEgNzkuMzMsMjEuMzY5IEM3Ny43OTgsMjIuMjU0IDc2LjA4NCwyMi43MjIgNzQuMzczLDIyLjcyMiBDNzIuMDgxLDIyLjcyMiA2OS45NTksMjEuODkgNjguMzk3LDIwLjM4IEw2OC4xNDUsMjAuMTM1IEM2Ny43MDYsMTkuNjcyIDY3LjMyMywxOS4xNTYgNjcuMDA2LDE4LjYwMSBDNjYuOTg4LDE4LjU1OSA2Ni45NjgsMTguNTE5IDY2Ljk0NiwxOC40NzkgTDY2LjcxOSwxOC4wNjUgQzY2LjY5LDE4LjAxMiA2Ni42NTgsMTcuOTYgNjYuNjI0LDE3LjkxMSBDNjUuNjg2LDE2LjMzNyA2My45NTEsMTUuMzY2IDYyLjA1MywxNS4zNjYgQzYxLjA0MiwxNS4zNjYgNjAuMDMzLDE1LjY0IDU5LjEzNiwxNi4xNTggTDMuMTI1LDQ4LjUwMiBDMC40MjYsNTAuMDYxIC0wLjYxMyw1My40NDIgMC44MTEsNTYuMDQgTDExLjA4OSw3NC43OSBDMTEuMjY2LDc1LjExMyAxMS41MzcsNzUuMzUzIDExLjg1LDc1LjQ5NCBMNTguMjc2LDEwMi4yOTggQzU5LjY3OSwxMDMuMTA4IDYxLjQzMywxMDMuNjMgNjMuMzQ4LDEwMy44MDYgQzYzLjgxMiwxMDMuODQ4IDY0LjI4NSwxMDMuODcgNjQuNzU0LDEwMy44NyBDNjUsMTAzLjg3IDY1LjI0OSwxMDMuODY0IDY1LjQ5NCwxMDMuODUyIEM2NS41NjMsMTAzLjg0OSA2NS42MzIsMTAzLjg0NyA2NS43MDEsMTAzLjg0NyBDNjUuNzY0LDEwMy44NDcgNjUuODI4LDEwMy44NDkgNjUuODksMTAzLjg1MiBDNjUuOTg2LDEwMy44NTYgNjYuMDgsMTAzLjg2MyA2Ni4xNzMsMTAzLjg3NCBDNjYuMjgyLDEwNS40NjcgNjcuMzMyLDEwNy4xOTcgNjguNzAyLDEwNy45ODggTDExMS4xNzQsMTMyLjUxIEMxMTEuNjk4LDEzMi44MTIgMTEyLjIzMiwxMzIuOTY1IDExMi43NjQsMTMyLjk2NSBDMTE0LjI2MSwxMzIuOTY1IDExNS4zNDcsMTMxLjc2NSAxMTUuMzQ3LDEzMC4xMTMgTDExNS4zNDcsMTAzLjU1MSBMMTIyLjQ1OCw5OS40NDYgQzEyMi44MTksOTkuMjM3IDEyMy4wODcsOTguODk4IDEyMy4yMDcsOTguNDk4IEwxMjcuODY1LDgyLjkwNSBDMTMyLjI3OSw4My43MDIgMTM2LjU1Nyw4NC43NTMgMTQwLjYwNyw4Ni4wMzMgTDE0MS4xNCw4Ni44NjIgQzE0MS40NTEsODcuMzQ2IDE0MS45NzcsODcuNjEzIDE0Mi41MTYsODcuNjEzIEMxNDIuNzk0LDg3LjYxMyAxNDMuMDc2LDg3LjU0MiAxNDMuMzMzLDg3LjM5MyBMMTY5Ljg2NSw3Mi4wNzYgTDE5Myw4NS40MzMgQzE5My41MjMsODUuNzM1IDE5NC4wNTgsODUuODg4IDE5NC41OSw4NS44ODggQzE5Ni4wODcsODUuODg4IDE5Ny4xNzMsODQuNjg5IDE5Ny4xNzMsODMuMDM2IEwxOTcuMTczLDI5LjAzNSBDMTk3LjE3MywyOC40NTEgMTk2Ljg2MSwyNy45MTEgMTk2LjM1NSwyNy42MTkgQzE5Ni4zNTUsMjcuNjE5IDE3MS44NDMsMTMuNDY3IDE3MC4zODUsMTIuNjI2IEMxNzAuMTMyLDEyLjQ4IDE2OS44NSwxMi40MDcgMTY5LjU2OCwxMi40MDcgQzE2OS4yODUsMTIuNDA3IDE2OS4wMDIsMTIuNDgxIDE2OC43NDksMTIuNjI3IEMxNjguMTQzLDEyLjk3OCAxNjUuNzU2LDE0LjM1NyAxNjQuNDI0LDE1LjEyNSBMMTU5LjYxNSwxMC44NyBDMTU4Ljc5NiwxMC4xNDUgMTU4LjE1NCw4LjkzNyAxNTguMDU0LDcuOTM0IEMxNTguMDQ1LDcuODM3IDE1OC4wMzQsNy43MzkgMTU4LjAyMSw3LjY0IEMxNTguMDA1LDcuNTIzIDE1Ny45OTgsNy40MSAxNTcuOTk4LDcuMzA0IEwxNTcuOTk4LDYuNDE4IEMxNTcuOTk4LDUuODM0IDE1Ny42ODYsNS4yOTUgMTU3LjE4MSw1LjAwMiBDMTU2LjYyNCw0LjY4IDE1MC40NDIsMS4xMTEgMTUwLjQ0MiwxLjExMSBDMTUwLjE4OSwwLjk2NSAxNDkuOTA3LDAuODkyIDE0OS42MjUsMC44OTIiIGlkPSJGaWxsLTEiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTYuMDI3LDI1LjYzNiBMMTQyLjYwMyw1Mi41MjcgQzE0My44MDcsNTMuMjIyIDE0NC41ODIsNTQuMTE0IDE0NC44NDUsNTUuMDY4IEwxNDQuODM1LDU1LjA3NSBMNjMuNDYxLDEwMi4wNTcgTDYzLjQ2LDEwMi4wNTcgQzYxLjgwNiwxMDEuOTA1IDYwLjI2MSwxMDEuNDU3IDU5LjA1NywxMDAuNzYyIEwxMi40ODEsNzMuODcxIEw5Ni4wMjcsMjUuNjM2IiBpZD0iRmlsbC0yIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYzLjQ2MSwxMDIuMTc0IEM2My40NTMsMTAyLjE3NCA2My40NDYsMTAyLjE3NCA2My40MzksMTAyLjE3MiBDNjEuNzQ2LDEwMi4wMTYgNjAuMjExLDEwMS41NjMgNTguOTk4LDEwMC44NjMgTDEyLjQyMiw3My45NzMgQzEyLjM4Niw3My45NTIgMTIuMzY0LDczLjkxNCAxMi4zNjQsNzMuODcxIEMxMi4zNjQsNzMuODMgMTIuMzg2LDczLjc5MSAxMi40MjIsNzMuNzcgTDk1Ljk2OCwyNS41MzUgQzk2LjAwNCwyNS41MTQgOTYuMDQ5LDI1LjUxNCA5Ni4wODUsMjUuNTM1IEwxNDIuNjYxLDUyLjQyNiBDMTQzLjg4OCw1My4xMzQgMTQ0LjY4Miw1NC4wMzggMTQ0Ljk1Nyw1NS4wMzcgQzE0NC45Nyw1NS4wODMgMTQ0Ljk1Myw1NS4xMzMgMTQ0LjkxNSw1NS4xNjEgQzE0NC45MTEsNTUuMTY1IDE0NC44OTgsNTUuMTc0IDE0NC44OTQsNTUuMTc3IEw2My41MTksMTAyLjE1OCBDNjMuNTAxLDEwMi4xNjkgNjMuNDgxLDEwMi4xNzQgNjMuNDYxLDEwMi4xNzQgTDYzLjQ2MSwxMDIuMTc0IFogTTEyLjcxNCw3My44NzEgTDU5LjExNSwxMDAuNjYxIEM2MC4yOTMsMTAxLjM0MSA2MS43ODYsMTAxLjc4MiA2My40MzUsMTAxLjkzNyBMMTQ0LjcwNyw1NS4wMTUgQzE0NC40MjgsNTQuMTA4IDE0My42ODIsNTMuMjg1IDE0Mi41NDQsNTIuNjI4IEw5Ni4wMjcsMjUuNzcxIEwxMi43MTQsNzMuODcxIEwxMi43MTQsNzMuODcxIFoiIGlkPSJGaWxsLTMiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ4LjMyNyw1OC40NzEgQzE0OC4xNDUsNTguNDggMTQ3Ljk2Miw1OC40OCAxNDcuNzgxLDU4LjQ3MiBDMTQ1Ljg4Nyw1OC4zODkgMTQ0LjQ3OSw1Ny40MzQgMTQ0LjYzNiw1Ni4zNCB
7196DMTQ0LjY4OSw1NS45NjcgMTQ0LjY2NCw1NS41OTcgMTQ0LjU2NCw1NS4yMzUgTDYzLjQ2MSwxMDIuMDU3IEM2NC4wODksMTAyLjExNSA2NC43MzMsMTAyLjEzIDY1LjM3OSwxMDIuMDk5IEM2NS41NjEsMTAyLjA5IDY1Ljc0MywxMDIuMDkgNjUuOTI1LDEwMi4wOTggQzY3LjgxOSwxMDIuMTgxIDY5LjIyNywxMDMuMTM2IDY5LjA3LDEwNC4yMyBMMTQ4LjMyNyw1OC40NzEiIGlkPSJGaWxsLTQiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNjkuMDcsMTA0LjM0NyBDNjkuMDQ4LDEwNC4zNDcgNjkuMDI1LDEwNC4zNCA2OS4wMDUsMTA0LjMyNyBDNjguOTY4LDEwNC4zMDEgNjguOTQ4LDEwNC4yNTcgNjguOTU1LDEwNC4yMTMgQzY5LDEwMy44OTYgNjguODk4LDEwMy41NzYgNjguNjU4LDEwMy4yODggQzY4LjE1MywxMDIuNjc4IDY3LjEwMywxMDIuMjY2IDY1LjkyLDEwMi4yMTQgQzY1Ljc0MiwxMDIuMjA2IDY1LjU2MywxMDIuMjA3IDY1LjM4NSwxMDIuMjE1IEM2NC43NDIsMTAyLjI0NiA2NC4wODcsMTAyLjIzMiA2My40NSwxMDIuMTc0IEM2My4zOTksMTAyLjE2OSA2My4zNTgsMTAyLjEzMiA2My4zNDcsMTAyLjA4MiBDNjMuMzM2LDEwMi4wMzMgNjMuMzU4LDEwMS45ODEgNjMuNDAyLDEwMS45NTYgTDE0NC41MDYsNTUuMTM0IEMxNDQuNTM3LDU1LjExNiAxNDQuNTc1LDU1LjExMyAxNDQuNjA5LDU1LjEyNyBDMTQ0LjY0Miw1NS4xNDEgMTQ0LjY2OCw1NS4xNyAxNDQuNjc3LDU1LjIwNCBDMTQ0Ljc4MSw1NS41ODUgMTQ0LjgwNiw1NS45NzIgMTQ0Ljc1MSw1Ni4zNTcgQzE0NC43MDYsNTYuNjczIDE0NC44MDgsNTYuOTk0IDE0NS4wNDcsNTcuMjgyIEMxNDUuNTUzLDU3Ljg5MiAxNDYuNjAyLDU4LjMwMyAxNDcuNzg2LDU4LjM1NSBDMTQ3Ljk2NCw1OC4zNjMgMTQ4LjE0Myw1OC4zNjMgMTQ4LjMyMSw1OC4zNTQgQzE0OC4zNzcsNTguMzUyIDE0OC40MjQsNTguMzg3IDE0OC40MzksNTguNDM4IEMxNDguNDU0LDU4LjQ5IDE0OC40MzIsNTguNTQ1IDE0OC4zODUsNTguNTcyIEw2OS4xMjksMTA0LjMzMSBDNjkuMTExLDEwNC4zNDIgNjkuMDksMTA0LjM0NyA2OS4wNywxMDQuMzQ3IEw2OS4wNywxMDQuMzQ3IFogTTY1LjY2NSwxMDEuOTc1IEM2NS43NTQsMTAxLjk3NSA2NS44NDIsMTAxLjk3NyA2NS45MywxMDEuOTgxIEM2Ny4xOTYsMTAyLjAzNyA2OC4yODMsMTAyLjQ2OSA2OC44MzgsMTAzLjEzOSBDNjkuMDY1LDEwMy40MTMgNjkuMTg4LDEwMy43MTQgNjkuMTk4LDEwNC4wMjEgTDE0Ny44ODMsNTguNTkyIEMxNDcuODQ3LDU4LjU5MiAxNDcuODExLDU4LjU5MSAxNDcuNzc2LDU4LjU4OSBDMTQ2LjUwOSw1OC41MzMgMTQ1LjQyMiw1OC4xIDE0NC44NjcsNTcuNDMxIEMxNDQuNTg1LDU3LjA5MSAxNDQuNDY1LDU2LjcwNyAxNDQuNTIsNTYuMzI0IEMxNDQuNTYzLDU2LjAyMSAxNDQuNTUyLDU1LjcxNiAxNDQuNDg4LDU1LjQxNCBMNjMuODQ2LDEwMS45NyBDNjQuMzUzLDEwMi4wMDIgNjQuODY3LDEwMi4wMDYgNjUuMzc0LDEwMS45ODIgQzY1LjQ3MSwxMDEuOTc3IDY1LjU2OCwxMDEuOTc1IDY1LjY2NSwxMDEuOTc1IEw2NS42NjUsMTAxLjk3NSBaIiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuMjA4LDU1LjEzNCBDMS4yMDcsNTMuMzA3IDEuOTY3LDUwLjkxNyAzLjkwNiw0OS43OTcgTDU5LjkxNywxNy40NTMgQzYxLjg1NiwxNi4zMzMgNjQuMjQxLDE2LjkwNyA2NS4yNDMsMTguNzM0IEw2NS40NzUsMTkuMTQ0IEM2NS44NzIsMTkuODgyIDY2LjM2OCwyMC41NiA2Ni45NDUsMjEuMTY1IEw2Ny4yMjMsMjEuNDM1IEM3MC41NDgsMjQuNjQ5IDc1LjgwNiwyNS4xNTEgODAuMTExLDIyLjY2NSBMODcuNDMsMTguNDQ1IEM4OS4zNywxNy4zMjYgOTEuNzU0LDE3Ljg5OSA5Mi43NTUsMTkuNzI3IEw5Ni4wMDUsMjUuNjU1IEwxMi40ODYsNzMuODg0IEwyLjIwOCw1NS4xMzQgWiIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMi40ODYsNzQuMDAxIEMxMi40NzYsNzQuMDAxIDEyLjQ2NSw3My45OTkgMTIuNDU1LDczLjk5NiBDMTIuNDI0LDczLjk4OCAxMi4zOTksNzMuOTY3IDEyLjM4NCw3My45NCBMMi4xMDYsNTUuMTkgQzEuMDc1LDUzLjMxIDEuODU3LDUwLjg0NSAzLjg0OCw0OS42OTYgTDU5Ljg1OCwxNy4zNTIgQzYwLjUyNSwxNi45NjcgNjEuMjcxLDE2Ljc2NCA2Mi4wMTYsMTYuNzY0IEM2My40MzEsMTYuNzY0IDY0LjY2NiwxNy40NjYgNjUuMzI3LDE4LjY0NiBDNjUuMzM3LDE4LjY1NCA2NS4zNDUsMTguNjYzIDY1LjM1MSwxOC42NzQgTDY1LjU3OCwxOS4wODggQzY1LjU4NCwxOS4xIDY1LjU4OSwxOS4xMTIgNjUuNTkxLDE5LjEyNiBDNjUuOTg1LDE5LjgzOCA2Ni40NjksMjAuNDk3IDY3LjAzLDIxLjA4NSBMNjcuMzA1LDIxLjM1MSBDNjkuMTUxLDIzLjEzNyA3MS42NDksMjQuMTIgNzQuMzM2LDI0LjEyIEM3Ni4zMTMsMjQuMTIgNzguMjksMjMuNTgyIDgwLjA1MywyMi41NjMgQzgwLjA2NCwyMi41NTcgODAuMDc2LDIyLjU1MyA4MC4wODgsMjIuNTUgTDg3LjM3MiwxOC4zNDQgQzg4LjAzOCwxNy45NTkgODguNzg0LDE3Ljc1NiA4OS41MjksMTcuNzU2IEM5MC45NTYsMTcuNzU2IDkyLjIwMSwxOC40NzIgOTIuODU4LDE5LjY3IEw5Ni4xMDcsMjUuNTk5IEM5Ni4xMzgsMjUuNjU0IDk2LjExOCwyNS43MjQgOTYuMDYzLDI1Ljc1NiBMMTIuNTQ1LDczLjk4NSBDMTIuNTI2LDczLjk5NiAxMi41MDYsNzQuMDAxIDEyLjQ4Niw3NC4wMDEgTDEyLjQ4Niw3NC4wMDEgWiBNNjIuMDE2LDE2Ljk5NyBDNjEuMzEyLDE2Ljk5NyA2MC42MDYsMTcuMTkgNTkuOTc1LDE3LjU1NCBMMy45NjUsNDkuODk5IEMyLjA4Myw1MC45ODUgMS4zNDEsNTMuMzA4IDIuMzEsNTUuMDc4IEwxMi41MzEsNzMuNzIzIEw5NS44NDgsMjUuNjExIEw5Mi42NTMsMTkuNzgyIEM5Mi4wMzgsMTguNjYgOTAuODcsMTcuOTkgODkuNTI5LDE3Ljk5IEM4OC44MjUsMTcuOTkgODguMTE5LDE4LjE4MiA4Ny40ODksMTguNTQ3IEw4MC4xNzIsMjIuNzcyIEM4MC4xNjEsMjIuNzc4IDgwLjE0OSwyMi43ODIgODAuMTM3LDIyLjc4NSBDNzguMzQ2LDIzLjgxMSA3Ni4zNDEsMjQuMzU0IDc0LjMzNiwyNC4zNTQgQzcxLjU4OCwyNC4zNTQgNjkuMDMzLDIzLjM0NyA2Ny4xNDIsMjEuNTE5IEw2Ni44NjQsMjEuMjQ5IEM2Ni4yNzcsMjAuNjM0IDY1Ljc3NCwxOS45NDcgNjUuMzY3LDE5LjIwMyBDNjUuMzYsMTkuMTkyIDY1LjM1NiwxOS4xNzkgNjUuMzU0LDE5LjE2NiBMNjUuMTYzLDE4LjgxOSBDNjUuMTU0LDE4LjgxMSA2NS4xNDYsMTguODAxIDY1LjE0LDE4Ljc5IEM2NC41MjUsMTcuNjY3IDYzLjM1NywxNi45OTcgNjIuMDE2LDE2Ljk5NyBMNjIuMDE2LDE2Ljk5NyBaIiBpZD0iRmlsbC03IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQyLjQzNCw0OC44MDggTDQyLjQzNCw0OC44MDggQzM5LjkyNCw0OC44MDcgMzcuNzM3LDQ3LjU1IDM2LjU4Miw0NS40NDMgQzM0Ljc3MSw0Mi4xMzkgMzYuMTQ0LDM3LjgwOSAzOS42NDEsMzUuNzg5IEw1MS45MzIsMjguNjkxIEM1My4xMDMsMjguMDE1IDU0LjQxMywyNy42NTggNTUuNzIxLDI3LjY1OCBDNTguMjMxLDI3LjY1OCA2MC40MTgsMjguOTE2IDYxLjU3MywzMS4wMjMgQzYzLjM4NCwzNC4zMjcgNjIuMDEyLDM4LjY1NyA1OC41MTQsNDAuNjc3IEw0Ni4yMjMsNDcuNzc1IEM0NS4wNTMsNDguNDUgNDMuNzQyLDQ4LjgwOCA0Mi40MzQsNDguODA4IEw0Mi40MzQsNDguODA4IFogTTU1LjcyMSwyOC4xMjUgQzU0LjQ5NSwyOC4xMjUgNTMuMjY1LDI4LjQ2MSA1Mi4xNjYsMjkuMDk2IEwzOS44NzUsMzYuMTk0IEMzNi41OTYsMzguMDg3IDM1LjMwMiw0Mi4xMzYgMzYuOTkyLDQ1LjIxOCBDMzguMDYzLDQ3LjE3MyA0MC4wOTgsNDguMzQgNDIuNDM0LDQ4LjM0IEM0My42NjEsNDguMzQgNDQuODksNDguMDA1IDQ1Ljk5LDQ3LjM3IEw1OC4yODEsNDAuMjcyIEM2MS41NiwzOC4zNzkgNjIuODUzLDM0LjMzIDYxLjE2NCwzMS4yNDggQzYwLjA5MiwyOS4yOTMgNTguMDU4LDI4LjEyNSA1NS43MjEsMjguMTI1IEw1NS43MjEsMjguMTI1IFoiIGlkPSJGaWxsLTgiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjU4OCwyLjQwNyBDMTQ5LjU4OCwyLjQwNyAxNTUuNzY4LDUuOTc1IDE1Ni4zMjUsNi4yOTcgTDE1Ni4zMjUsNy4xODQgQzE1Ni4zMjUsNy4zNiAxNTYuMzM4LDcuNTQ0IDE1Ni4zNjIsNy43MzMgQzE1Ni4zNzMsNy44MTQgMTU2LjM4Miw3Ljg5NCAxNTYuMzksNy45NzUgQzE1Ni41Myw5LjM5IDE1Ny4zNjMsMTAuOTczIDE1OC40OTUsMTEuOTc0IEwxNjUuODkxLDE4LjUxOSBDMTY2LjA2OCwxOC42NzUgMTY2LjI0OSwxOC44MTQgMTY2LjQzMiwxOC45MzQgQzE2OC4wMTEsMTkuOTc0IDE2OS4zODIsMTkuNCAxNjkuNDk0LDE3LjY1MiBDMTY5LjU0MywxNi44NjggMTY5LjU1MSwxNi4wNTcgMTY5LjUxNywxNS4yMjMgTDE2OS41MTQsMTUuMDYzIEwxNjkuNTE0LDEzLjkxMiBDMTcwLjc4LDE0LjY0MiAxOTUuNTAxLDI4LjkxNSAxOTUuNTAxLDI4LjkxNSBMMTk1LjUwMSw4Mi45MTUgQzE5NS41MDEsODQuMDA1IDE5NC43MzEsODQuNDQ1IDE5My43ODEsODMuODk3IEwxNTEuMzA4LDU5LjM3NCBDMTUwLjM1OCw1OC44MjYgMTQ5LjU4OCw1Ny40OTcgMTQ5LjU4OCw1Ni40MDggTDE0OS41ODgsMjIuMzc1IiBpZD0iRmlsbC05IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE5NC41NTMsODQuMjUgQzE5NC4yOTYsODQuMjUgMTk0LjAxMyw4NC4xNjUgMTkzLjcyMiw4My45OTcgTDE1MS4yNSw1OS40NzYgQzE1MC4yNjksNTguOTA5IDE0OS40NzEsNTcuNTMzIDE0OS40NzEsNTYuNDA4IEwxNDkuNDcxLDIyLjM3NSBMMTQ5LjcwNSwyMi4zNzUgTDE0OS43MDUsNTYuNDA4IEMxNDkuNzA1LDU3LjQ1OSAxNTAuNDUsNTguNzQ0IDE1MS4zNjYsNTkuMjc0IEwxOTMuODM5LDgzLjc5NSBDMTk0LjI2Myw4NC4wNCAxOTQuNjU1LDg0LjA4MyAxOTQuOTQyLDgzLjkxNyBDMTk1LjIyNyw4My43NTMgMTk1LjM4NCw4My4zOTcgMTk1LjM4NCw4Mi45MTUgTDE5NS4zODQsMjguOTgyIEMxOTQuMTAyLDI4LjI0MiAxNzIuMTA0LDE1LjU0MiAxNjkuNjMxLDE0LjExNCBMMTY5LjYzNCwxNS4yMiBDMTY5LjY2OCwxNi4wNTIgMTY5LjY2LDE2Ljg3NCAxNjkuNjEsMTcuNjU5IEMxNjkuNTU2LDE4LjUwMyAxNjkuMjE0LDE
71965LjEyMyAxNjguNjQ3LDE5LjQwNSBDMTY4LjAyOCwxOS43MTQgMTY3LjE5NywxOS41NzggMTY2LjM2NywxOS4wMzIgQzE2Ni4xODEsMTguOTA5IDE2NS45OTUsMTguNzY2IDE2NS44MTQsMTguNjA2IEwxNTguNDE3LDEyLjA2MiBDMTU3LjI1OSwxMS4wMzYgMTU2LjQxOCw5LjQzNyAxNTYuMjc0LDcuOTg2IEMxNTYuMjY2LDcuOTA3IDE1Ni4yNTcsNy44MjcgMTU2LjI0Nyw3Ljc0OCBDMTU2LjIyMSw3LjU1NSAxNTYuMjA5LDcuMzY1IDE1Ni4yMDksNy4xODQgTDE1Ni4yMDksNi4zNjQgQzE1NS4zNzUsNS44ODMgMTQ5LjUyOSwyLjUwOCAxNDkuNTI5LDIuNTA4IEwxNDkuNjQ2LDIuMzA2IEMxNDkuNjQ2LDIuMzA2IDE1NS44MjcsNS44NzQgMTU2LjM4NCw2LjE5NiBMMTU2LjQ0Miw2LjIzIEwxNTYuNDQyLDcuMTg0IEMxNTYuNDQyLDcuMzU1IDE1Ni40NTQsNy41MzUgMTU2LjQ3OCw3LjcxNyBDMTU2LjQ4OSw3LjggMTU2LjQ5OSw3Ljg4MiAxNTYuNTA3LDcuOTYzIEMxNTYuNjQ1LDkuMzU4IDE1Ny40NTUsMTAuODk4IDE1OC41NzIsMTEuODg2IEwxNjUuOTY5LDE4LjQzMSBDMTY2LjE0MiwxOC41ODQgMTY2LjMxOSwxOC43MiAxNjYuNDk2LDE4LjgzNyBDMTY3LjI1NCwxOS4zMzYgMTY4LDE5LjQ2NyAxNjguNTQzLDE5LjE5NiBDMTY5LjAzMywxOC45NTMgMTY5LjMyOSwxOC40MDEgMTY5LjM3NywxNy42NDUgQzE2OS40MjcsMTYuODY3IDE2OS40MzQsMTYuMDU0IDE2OS40MDEsMTUuMjI4IEwxNjkuMzk3LDE1LjA2NSBMMTY5LjM5NywxMy43MSBMMTY5LjU3MiwxMy44MSBDMTcwLjgzOSwxNC41NDEgMTk1LjU1OSwyOC44MTQgMTk1LjU1OSwyOC44MTQgTDE5NS42MTgsMjguODQ3IEwxOTUuNjE4LDgyLjkxNSBDMTk1LjYxOCw4My40ODQgMTk1LjQyLDgzLjkxMSAxOTUuMDU5LDg0LjExOSBDMTk0LjkwOCw4NC4yMDYgMTk0LjczNyw4NC4yNSAxOTQuNTUzLDg0LjI1IiBpZD0iRmlsbC0xMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDUuNjg1LDU2LjE2MSBMMTY5LjgsNzAuMDgzIEwxNDMuODIyLDg1LjA4MSBMMTQyLjM2LDg0Ljc3NCBDMTM1LjgyNiw4Mi42MDQgMTI4LjczMiw4MS4wNDYgMTIxLjM0MSw4MC4xNTggQzExNi45NzYsNzkuNjM0IDExMi42NzgsODEuMjU0IDExMS43NDMsODMuNzc4IEMxMTEuNTA2LDg0LjQxNCAxMTEuNTAzLDg1LjA3MSAxMTEuNzMyLDg1LjcwNiBDMTEzLjI3LDg5Ljk3MyAxMTUuOTY4LDk0LjA2OSAxMTkuNzI3LDk3Ljg0MSBMMTIwLjI1OSw5OC42ODYgQzEyMC4yNiw5OC42ODUgOTQuMjgyLDExMy42ODMgOTQuMjgyLDExMy42ODMgTDcwLjE2Nyw5OS43NjEgTDE0NS42ODUsNTYuMTYxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05NC4yODIsMTEzLjgxOCBMOTQuMjIzLDExMy43ODUgTDY5LjkzMyw5OS43NjEgTDcwLjEwOCw5OS42NiBMMTQ1LjY4NSw1Ni4wMjYgTDE0NS43NDMsNTYuMDU5IEwxNzAuMDMzLDcwLjA4MyBMMTQzLjg0Miw4NS4yMDUgTDE0My43OTcsODUuMTk1IEMxNDMuNzcyLDg1LjE5IDE0Mi4zMzYsODQuODg4IDE0Mi4zMzYsODQuODg4IEMxMzUuNzg3LDgyLjcxNCAxMjguNzIzLDgxLjE2MyAxMjEuMzI3LDgwLjI3NCBDMTIwLjc4OCw4MC4yMDkgMTIwLjIzNiw4MC4xNzcgMTE5LjY4OSw4MC4xNzcgQzExNS45MzEsODAuMTc3IDExMi42MzUsODEuNzA4IDExMS44NTIsODMuODE5IEMxMTEuNjI0LDg0LjQzMiAxMTEuNjIxLDg1LjA1MyAxMTEuODQyLDg1LjY2NyBDMTEzLjM3Nyw4OS45MjUgMTE2LjA1OCw5My45OTMgMTE5LjgxLDk3Ljc1OCBMMTE5LjgyNiw5Ny43NzkgTDEyMC4zNTIsOTguNjE0IEMxMjAuMzU0LDk4LjYxNyAxMjAuMzU2LDk4LjYyIDEyMC4zNTgsOTguNjI0IEwxMjAuNDIyLDk4LjcyNiBMMTIwLjMxNyw5OC43ODcgQzEyMC4yNjQsOTguODE4IDk0LjU5OSwxMTMuNjM1IDk0LjM0LDExMy43ODUgTDk0LjI4MiwxMTMuODE4IEw5NC4yODIsMTEzLjgxOCBaIE03MC40MDEsOTkuNzYxIEw5NC4yODIsMTEzLjU0OSBMMTE5LjA4NCw5OS4yMjkgQzExOS42Myw5OC45MTQgMTE5LjkzLDk4Ljc0IDEyMC4xMDEsOTguNjU0IEwxMTkuNjM1LDk3LjkxNCBDMTE1Ljg2NCw5NC4xMjcgMTEzLjE2OCw5MC4wMzMgMTExLjYyMiw4NS43NDYgQzExMS4zODIsODUuMDc5IDExMS4zODYsODQuNDA0IDExMS42MzMsODMuNzM4IEMxMTIuNDQ4LDgxLjUzOSAxMTUuODM2LDc5Ljk0MyAxMTkuNjg5LDc5Ljk0MyBDMTIwLjI0Niw3OS45NDMgMTIwLjgwNiw3OS45NzYgMTIxLjM1NSw4MC4wNDIgQzEyOC43NjcsODAuOTMzIDEzNS44NDYsODIuNDg3IDE0Mi4zOTYsODQuNjYzIEMxNDMuMjMyLDg0LjgzOCAxNDMuNjExLDg0LjkxNyAxNDMuNzg2LDg0Ljk2NyBMMTY5LjU2Niw3MC4wODMgTDE0NS42ODUsNTYuMjk1IEw3MC40MDEsOTkuNzYxIEw3MC40MDEsOTkuNzYxIFoiIGlkPSJGaWxsLTEyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2Ny4yMywxOC45NzkgTDE2Ny4yMyw2OS44NSBMMTM5LjkwOSw4NS42MjMgTDEzMy40NDgsNzEuNDU2IEMxMzIuNTM4LDY5LjQ2IDEzMC4wMiw2OS43MTggMTI3LjgyNCw3Mi4wMyBDMTI2Ljc2OSw3My4xNCAxMjUuOTMxLDc0LjU4NSAxMjUuNDk0LDc2LjA0OCBMMTE5LjAzNCw5Ny42NzYgTDkxLjcxMiwxMTMuNDUgTDkxLjcxMiw2Mi41NzkgTDE2Ny4yMywxOC45NzkiIGlkPSJGaWxsLTEzIiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkxLjcxMiwxMTMuNTY3IEM5MS42OTIsMTEzLjU2NyA5MS42NzIsMTEzLjU2MSA5MS42NTMsMTEzLjU1MSBDOTEuNjE4LDExMy41MyA5MS41OTUsMTEzLjQ5MiA5MS41OTUsMTEzLjQ1IEw5MS41OTUsNjIuNTc5IEM5MS41OTUsNjIuNTM3IDkxLjYxOCw2Mi40OTkgOTEuNjUzLDYyLjQ3OCBMMTY3LjE3MiwxOC44NzggQzE2Ny4yMDgsMTguODU3IDE2Ny4yNTIsMTguODU3IDE2Ny4yODgsMTguODc4IEMxNjcuMzI0LDE4Ljg5OSAxNjcuMzQ3LDE4LjkzNyAxNjcuMzQ3LDE4Ljk3OSBMMTY3LjM0Nyw2OS44NSBDMTY3LjM0Nyw2OS44OTEgMTY3LjMyNCw2OS45MyAxNjcuMjg4LDY5Ljk1IEwxMzkuOTY3LDg1LjcyNSBDMTM5LjkzOSw4NS43NDEgMTM5LjkwNSw4NS43NDUgMTM5Ljg3Myw4NS43MzUgQzEzOS44NDIsODUuNzI1IDEzOS44MTYsODUuNzAyIDEzOS44MDIsODUuNjcyIEwxMzMuMzQyLDcxLjUwNCBDMTMyLjk2Nyw3MC42ODIgMTMyLjI4LDcwLjIyOSAxMzEuNDA4LDcwLjIyOSBDMTMwLjMxOSw3MC4yMjkgMTI5LjA0NCw3MC45MTUgMTI3LjkwOCw3Mi4xMSBDMTI2Ljg3NCw3My4yIDEyNi4wMzQsNzQuNjQ3IDEyNS42MDYsNzYuMDgyIEwxMTkuMTQ2LDk3LjcwOSBDMTE5LjEzNyw5Ny43MzggMTE5LjExOCw5Ny43NjIgMTE5LjA5Miw5Ny43NzcgTDkxLjc3LDExMy41NTEgQzkxLjc1MiwxMTMuNTYxIDkxLjczMiwxMTMuNTY3IDkxLjcxMiwxMTMuNTY3IEw5MS43MTIsMTEzLjU2NyBaIE05MS44MjksNjIuNjQ3IEw5MS44MjksMTEzLjI0OCBMMTE4LjkzNSw5Ny41OTggTDEyNS4zODIsNzYuMDE1IEMxMjUuODI3LDc0LjUyNSAxMjYuNjY0LDczLjA4MSAxMjcuNzM5LDcxLjk1IEM
7196xMjguOTE5LDcwLjcwOCAxMzAuMjU2LDY5Ljk5NiAxMzEuNDA4LDY5Ljk5NiBDMTMyLjM3Nyw2OS45OTYgMTMzLjEzOSw3MC40OTcgMTMzLjU1NCw3MS40MDcgTDEzOS45NjEsODUuNDU4IEwxNjcuMTEzLDY5Ljc4MiBMMTY3LjExMywxOS4xODEgTDkxLjgyOSw2Mi42NDcgTDkxLjgyOSw2Mi42NDcgWiIgaWQ9IkZpbGwtMTQiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTY4LjU0MywxOS4yMTMgTDE2OC41NDMsNzAuMDgzIEwxNDEuMjIxLDg1Ljg1NyBMMTM0Ljc2MSw3MS42ODkgQzEzMy44NTEsNjkuNjk0IDEzMS4zMzMsNjkuOTUxIDEyOS4xMzcsNzIuMjYzIEMxMjguMDgyLDczLjM3NCAxMjcuMjQ0LDc0LjgxOSAxMjYuODA3LDc2LjI4MiBMMTIwLjM0Niw5Ny45MDkgTDkzLjAyNSwxMTMuNjgzIEw5My4wMjUsNjIuODEzIEwxNjguNTQzLDE5LjIxMyIgaWQ9IkZpbGwtMTUiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTMuMDI1LDExMy44IEM5My4wMDUsMTEzLjggOTIuOTg0LDExMy43OTUgOTIuOTY2LDExMy43ODUgQzkyLjkzMSwxMTMuNzY0IDkyLjkwOCwxMTMuNzI1IDkyLjkwOCwxMTMuNjg0IEw5Mi45MDgsNjIuODEzIEM5Mi45MDgsNjIuNzcxIDkyLjkzMSw2Mi43MzMgOTIuOTY2LDYyLjcxMiBMMTY4LjQ4NCwxOS4xMTIgQzE2OC41MiwxOS4wOSAxNjguNTY1LDE5LjA5IDE2OC42MDEsMTkuMTEyIEMxNjguNjM3LDE5LjEzMiAxNjguNjYsMTkuMTcxIDE2OC42NiwxOS4yMTIgTDE2OC42Niw3MC4wODMgQzE2OC42Niw3MC4xMjUgMTY4LjYzNyw3MC4xNjQgMTY4LjYwMSw3MC4xODQgTDE0MS4yOCw4NS45NTggQzE0MS4yNTEsODUuOTc1IDE0MS4yMTcsODUuOTc5IDE0MS4xODYsODUuOTY4IEMxNDEuMTU0LDg1Ljk1OCAxNDEuMTI5LDg1LjkzNiAxNDEuMTE1LDg1LjkwNiBMMTM0LjY1NSw3MS43MzggQzEzNC4yOCw3MC45MTUgMTMzLjU5Myw3MC40NjMgMTMyLjcyLDcwLjQ2MyBDMTMxLjYzMiw3MC40NjMgMTMwLjM1Nyw3MS4xNDggMTI5LjIyMSw3Mi4zNDQgQzEyOC4xODYsNzMuNDMzIDEyNy4zNDcsNzQuODgxIDEyNi45MTksNzYuMzE1IEwxMjAuNDU4LDk3Ljk0MyBDMTIwLjQ1LDk3Ljk3MiAxMjAuNDMxLDk3Ljk5NiAxMjAuNDA1LDk4LjAxIEw5My4wODMsMTEzLjc4NSBDOTMuMDY1LDExMy43OTUgOTMuMDQ1LDExMy44IDkzLjAyNSwxMTMuOCBMOTMuMDI1LDExMy44IFogTTkzLjE0Miw2Mi44ODEgTDkzLjE0MiwxMTMuNDgxIEwxMjAuMjQ4LDk3LjgzMiBMMTI2LjY5NSw3Ni4yNDggQzEyNy4xNCw3NC43NTggMTI3Ljk3Nyw3My4zMTUgMTI5LjA1Miw3Mi4xODMgQzEzMC4yMzEsNzAuOTQyIDEzMS41NjgsNzAuMjI5IDEzMi43Miw3MC4yMjkgQzEzMy42ODksNzAuMjI5IDEzNC40NTIsNzAuNzMxIDEzNC44NjcsNzEuNjQxIEwxNDEuMjc0LDg1LjY5MiBMMTY4LjQyNiw3MC4wMTYgTDE2OC40MjYsMTkuNDE1IEw5My4xNDIsNjIuODgxIEw5My4xNDIsNjIuODgxIFoiIGlkPSJGaWxsLTE2IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS44LDcwLjA4MyBMMTQyLjQ3OCw4NS44NTcgTDEzNi4wMTgsNzEuNjg5IEMxMzUuMTA4LDY5LjY5NCAxMzIuNTksNjkuOTUxIDEzMC4zOTMsNzIuMjYzIEMxMjkuMzM5LDczLjM3NCAxMjguNSw3NC44MTkgMTI4LjA2NCw3Ni4yODIgTDEyMS42MDMsOTcuOTA5IEw5NC4yODIsMTEzLjY4MyBMOTQuMjgyLDYyLjgxMyBMMTY5LjgsMTkuMjEzIEwxNjkuOCw3MC4wODMgWiIgaWQ9IkZpbGwtMTciIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTQuMjgyLDExMy45MTcgQzk0LjI0MSwxMTMuOTE3IDk0LjIwMSwxMTMuOTA3IDk0LjE2NSwxMTMuODg2IEM5NC4wOTMsMTEzLjg0NSA5NC4wNDgsMTEzLjc2NyA5NC4wNDgsMTEzLjY4NCBMOTQuMDQ4LDYyLjgxMyBDOTQuMDQ4LDYyLjczIDk0LjA5Myw2Mi42NTIgOTQuMTY1LDYyLjYxMSBMMTY5LjY4MywxOS4wMSBDMTY5Ljc1NSwxOC45NjkgMTY5Ljg0NCwxOC45NjkgMTY5LjkxNywxOS4wMSBDMTY5Ljk4OSwxOS4wNTIgMTcwLjAzMywxOS4xMjkgMTcwLjAzMywxOS4yMTIgTDE3MC4wMzMsNzAuMDgzIEMxNzAuMDMzLDcwLjE2NiAxNjkuOTg5LDcwLjI0NCAxNjkuOTE3LDcwLjI4NSBMMTQyLjU5NSw4Ni4wNiBDMTQyLjUzOCw4Ni4wOTIgMTQyLjQ2OSw4Ni4xIDE0Mi40MDcsODYuMDggQzE0Mi4zNDQsODYuMDYgMTQyLjI5Myw4Ni4wMTQgMTQyLjI2Niw4NS45NTQgTDEzNS44MDUsNzEuNzg2IEMxMzUuNDQ1LDcwLjk5NyAxMzQuODEzLDcwLjU4IDEzMy45NzcsNzAuNTggQzEzMi45MjEsNzAuNTggMTMxLjY3Niw3MS4yNTIgMTMwLjU2Miw3Mi40MjQgQzEyOS41NCw3My41MDEgMTI4LjcxMSw3NC45MzEgMTI4LjI4Nyw3Ni4zNDggTDEyMS44MjcsOTcuOTc2IEMxMjEuODEsOTguMDM0IDEyMS43NzEsOTguMDgyIDEyMS43Miw5OC4xMTIgTDk0LjM5OCwxMTMuODg2IEM5NC4zNjIsMTEzLjkwNyA5NC4zMjIsMTEzLjkxNyA5NC4yODIsMTEzLjkxNyBMOTQuMjgyLDExMy45MTcgWiBNOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDExMy4yNzkgTDEyMS40MDYsOTcuNzU0IEwxMjcuODQsNzYuMjE1IEMxMjguMjksNzQuNzA4IDEyOS4xMzcsNzMuMjQ3IDEzMC4yMjQsNzIuMTAzIEMxMzEuNDI1LDcwLjgzOCAxMzIuNzkzLDcwLjExMiAxMzMuOTc3LDcwLjExMiBDMTM0Ljk5NSw3MC4xMTIgMTM1Ljc5NSw3MC42MzggMTM2LjIzLDcxLjU5MiBMMTQyLjU4NCw4NS41MjYgTDE2OS41NjYsNjkuOTQ4IEwxNjkuNTY2LDE5LjYxNyBMOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDYyLjk0OCBaIiBpZD0iRmlsbC0xOCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMDkuODk0LDkyLjk0MyBMMTA5Ljg5NCw5Mi45NDMgQzEwOC4xMiw5Mi45NDMgMTA2LjY1Myw5Mi4yMTggMTA1LjY1LDkwLjgyMyBDMTA1LjU4Myw5MC43MzEgMTA1LjU5Myw5MC42MSAxMDUuNjczLDkwLjUyOSBDMTA1Ljc1Myw5MC40NDggMTA1Ljg4LDkwLjQ0IDEwNS45NzQsOTAuNTA2IEMxMDYuNzU0LDkxLjA1MyAxMDcuNjc5LDkxLjMzMyAxMDguNzI0LDkxLjMzMyBDMTEwLjA0Nyw5MS4zMzMgMTExLjQ3OCw5MC44OTQgMTEyLjk4LDkwLjAyNyBDMTE4LjI5MSw4Ni45NiAxMjIuNjExLDc5LjUwOSAxMjIuNjExLDczLjQxNiBDMTIyLjYxMSw3MS40ODkgMTIyLjE2OSw2OS44NTYgMTIxLjMzMyw2OC42OTIgQzEyMS4yNjYsNjguNiAxMjEuMjc2LDY4LjQ3MyAxMjEuMzU2LDY4LjM5MiBDMTIxLjQzNiw2OC4zMTEgMTIxLjU2Myw2OC4yOTkgMTIxLjY1Niw2OC4zNjUgQzEyMy4zMjcsNjkuNTM3IDEyNC4yNDcsNzEuNzQ2IDEyNC4yNDcsNzQuNTg0IEMxMjQuMjQ3LDgwLjgyNiAxMTkuODIxLDg4LjQ0NyAxMTQuMzgyLDkxLjU4NyBDMTEyLjgwOCw5Mi40OTUgMTExLjI5OCw5Mi45NDMgMTA5Ljg5NCw5Mi45NDMgTDEwOS44OTQsOTIuOTQzIFogTTEwNi45MjUsOTEuNDAxIEMxMDcuNzM4LDkyLjA1MiAxMDguNzQ1LDkyLjI3OCAxMDkuODkzLDkyLjI3OCBMMTA5Ljg5NCw5Mi4yNzggQzExMS4y
7196MTUsOTIuMjc4IDExMi42NDcsOTEuOTUxIDExNC4xNDgsOTEuMDg0IEMxMTkuNDU5LDg4LjAxNyAxMjMuNzgsODAuNjIxIDEyMy43OCw3NC41MjggQzEyMy43OCw3Mi41NDkgMTIzLjMxNyw3MC45MjkgMTIyLjQ1NCw2OS43NjcgQzEyMi44NjUsNzAuODAyIDEyMy4wNzksNzIuMDQyIDEyMy4wNzksNzMuNDAyIEMxMjMuMDc5LDc5LjY0NSAxMTguNjUzLDg3LjI4NSAxMTMuMjE0LDkwLjQyNSBDMTExLjY0LDkxLjMzNCAxMTAuMTMsOTEuNzQyIDEwOC43MjQsOTEuNzQyIEMxMDguMDgzLDkxLjc0MiAxMDcuNDgxLDkxLjU5MyAxMDYuOTI1LDkxLjQwMSBMMTA2LjkyNSw5MS40MDEgWiIgaWQ9IkZpbGwtMTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjA5Nyw5MC4yMyBDMTE4LjQ4MSw4Ny4xMjIgMTIyLjg0NSw3OS41OTQgMTIyLjg0NSw3My40MTYgQzEyMi44NDUsNzEuMzY1IDEyMi4zNjIsNjkuNzI0IDEyMS41MjIsNjguNTU2IEMxMTkuNzM4LDY3LjMwNCAxMTcuMTQ4LDY3LjM2MiAxMTQuMjY1LDY5LjAyNiBDMTA4Ljg4MSw3Mi4xMzQgMTA0LjUxNyw3OS42NjIgMTA0LjUxNyw4NS44NCBDMTA0LjUxNyw4Ny44OTEgMTA1LDg5LjUzMiAxMDUuODQsOTAuNyBDMTA3LjYyNCw5MS45NTIgMTEwLjIxNCw5MS44OTQgMTEzLjA5Nyw5MC4yMyIgaWQ9IkZpbGwtMjAiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTA4LjcyNCw5MS42MTQgTDEwOC43MjQsOTEuNjE0IEMxMDcuNTgyLDkxLjYxNCAxMDYuNTY2LDkxLjQwMSAxMDUuNzA1LDkwLjc5NyBDMTA1LjY4NCw5MC43ODMgMTA1LjY2NSw5MC44MTEgMTA1LjY1LDkwLjc5IEMxMDQuNzU2LDg5LjU0NiAxMDQuMjgzLDg3Ljg0MiAxMDQuMjgzLDg1LjgxNyBDMTA0LjI4Myw3OS41NzUgMTA4LjcwOSw3MS45NTMgMTE0LjE0OCw2OC44MTIgQzExNS43MjIsNjcuOTA0IDExNy4yMzIsNjcuNDQ5IDExOC42MzgsNjcuNDQ5IEMxMTkuNzgsNjcuNDQ5IDEyMC43OTYsNjcuNzU4IDEyMS42NTYsNjguMzYyIEMxMjEuNjc4LDY4LjM3NyAxMjEuNjk3LDY4LjM5NyAxMjEuNzEyLDY4LjQxOCBDMTIyLjYwNiw2OS42NjIgMTIzLjA3OSw3MS4zOSAxMjMuMDc5LDczLjQxNSBDMTIzLjA3OSw3OS42NTggMTE4LjY1Myw4Ny4xOTggMTEzLjIxNCw5MC4zMzggQzExMS42NCw5MS4yNDcgMTEwLjEzLDkxLjYxNCAxMDguNzI0LDkxLjYxNCBMMTA4LjcyNCw5MS42MTQgWiBNMTA2LjAwNiw5MC41MDUgQzEwNi43OCw5MS4wMzcgMTA3LjY5NCw5MS4yODEgMTA4LjcyNCw5MS4yODEgQzExMC4wNDcsOTEuMjgxIDExMS40NzgsOTAuODY4IDExMi45OCw5MC4wMDEgQzExOC4yOTEsODYuOTM1IDEyMi42MTEsNzkuNDk2IDEyMi42MTEsNzMuNDAzIEMxMjIuNjExLDcxLjQ5NCAxMjIuMTc3LDY5Ljg4IDEyMS4zNTYsNjguNzE4IEMxMjAuNTgyLDY4LjE4NSAxMTkuNjY4LDY3LjkxOSAxMTguNjM4LDY3LjkxOSBDMTE3LjMxNSw2Ny45MTkgMTE1Ljg4Myw2OC4zNiAxMTQuMzgyLDY5LjIyNyBDMTA5LjA3MSw3Mi4yOTMgMTA0Ljc1MSw3OS43MzMgMTA0Ljc1MSw4NS44MjYgQzEwNC43NTEsODcuNzM1IDEwNS4xODUsODkuMzQzIDEwNi4wMDYsOTAuNTA1IEwxMDYuMDA2LDkwLjUwNSBaIiBpZD0iRmlsbC0yMSIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDkuMzE4LDcuMjYyIEwxMzkuMzM0LDE2LjE0IEwxNTUuMjI3LDI3LjE3MSBMMTYwLjgxNiwyMS4wNTkgTDE0OS4zMTgsNy4yNjIiIGlkPSJGaWxsLTIyIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS42NzYsMTMuODQgTDE1OS45MjgsMTkuNDY3IEMxNTYuMjg2LDIxLjU3IDE1MC40LDIxLjU4IDE0Ni43ODEsMTkuNDkxIEMxNDMuMTYxLDE3LjQwMiAxNDMuMTgsMTQuMDAzIDE0Ni44MjIsMTEuOSBMMTU2LjMxNyw2LjI5MiBMMTQ5LjU4OCwyLjQwNyBMNjcuNzUyLDQ5LjQ3OCBMMTEzLjY3NSw3NS45OTIgTDExNi43NTYsNzQuMjEzIEMxMTcuMzg3LDczLjg0OCAxMTcuNjI1LDczLjMxNSAxMTcuMzc0LDcyLjgyMyBDMTE1LjAxNyw2OC4xOTEgMTE0Ljc4MSw2My4yNzcgMTE2LjY5MSw1OC41NjEgQzEyMi4zMjksNDQuNjQxIDE0MS4yLDMzLjc0NiAxNjUuMzA5LDMwLjQ5MSBDMTczLjQ3OCwyOS4zODggMTgxLjk4OSwyOS41MjQgMTkwLjAxMywzMC44ODUgQzE5MC44NjUsMzEuMDMgMTkxLjc4OSwzMC44OTMgMTkyLjQyLDMwLjUyOCBMMTk1LjUwMSwyOC43NSBMMTY5LjY3NiwxMy44NCIgaWQ9IkZpbGwtMjMiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3Ni40NTkgQzExMy41OTQsNzYuNDU5IDExMy41MTQsNzYuNDM4IDExMy40NDIsNzYuMzk3IEw2Ny41MTgsNDkuODgyIEM2Ny4zNzQsNDkuNzk5IDY3LjI4NCw0OS42NDUgNjcuMjg1LDQ5LjQ3OCBDNjcuMjg1LDQ5LjMxMSA2Ny4zNzQsNDkuMTU3IDY3LjUxOSw0OS4wNzMgTDE0OS4zNTUsMi4wMDIgQzE0OS40OTksMS45MTkgMTQ5LjY3NywxLjkxOSAxNDkuODIxLDIuMDAyIEwxNTYuNTUsNS44ODcgQzE1Ni43NzQsNi4wMTcgMTU2Ljg1LDYuMzAyIDE1Ni43MjIsNi41MjYgQzE1Ni41OTIsNi43NDkgMTU2LjMwNyw2LjgyNiAxNTYuMDgzLDYuNjk2IEwxNDkuNTg3LDIuOTQ2IEw2OC42ODcsNDkuNDc5IEwxMTMuNjc1LDc1LjQ1MiBMMTE2LjUyMyw3My44MDggQzExNi43MTUsNzMuNjk3IDExNy4xNDMsNzMuMzk5IDExNi45NTgsNzMuMDM1IEMxMTQuNTQyLDY4LjI4NyAxMTQuMyw2My4yMjEgMTE2LjI1OCw1OC4zODUgQzExOS4wNjQsNTEuNDU4IDEyNS4xNDMsNDUuMTQzIDEzMy44NCw0MC4xMjIgQzE0Mi40OTcsMzUuMTI0IDE1My4zNTgsMzEuNjMzIDE2NS4yNDcsMzAuMDI4IEMxNzMuNDQ1LDI4LjkyMSAxODIuMDM3LDI5LjA1OCAxOTAuMDkxLDMwLjQyNSBDMTkwLjgzLDMwLjU1IDE5MS42NTIsMzAuNDMyIDE5Mi4xODYsMzAuMTI0IEwxOTQuNTY3LDI4Ljc1IEwxNjkuNDQyLDE0LjI0NCBDMTY5LjIxOSwxNC4xMTUgMTY5LjE0MiwxMy44MjkgMTY5LjI3MSwxMy42MDYgQzE2OS40LDEzLjM4MiAxNjkuNjg1LDEzLjMwNiAxNjkuOTA5LDEzLjQzNSBMMTk1LjczNCwyOC4zNDUgQzE5NS44NzksMjguNDI4IDE5NS45NjgsMjguNTgzIDE5NS45NjgsMjguNzUgQzE5NS45NjgsMjguOTE2IDE5NS44NzksMjkuMDcxIDE5NS43MzQsMjkuMTU0IEwxOTIuNjUzLDMwLjkzMyBDMTkxLjkzMiwzMS4zNSAxOTAuODksMzEuNTA4IDE4OS45MzUsMzEuMzQ2IEMxODEuOTcyLDI5Ljk5NSAxNzMuNDc4LDI5Ljg2IDE2NS4zNzIsMzAuOTU0IEMxNTMuNjAyLDMyLjU0MyAxNDIuODYsMzUuOTkzIDEzNC4zMDcsNDAuOTMxIEMxMjUuNzkzLDQ1Ljg0NyAxMTkuODUxLDUyLjAwNCAxMTcuMTI0LDU4LjczNiBDMTE1LjI3LDYzLjMxNCAxMTUuNTAxLDY4LjExMiAxMTcuNzksNzIuNjExIEMxMTguMTYsNzMuMzM2IDExNy44NDUsNzQuMTI0IDExNi45OSw3NC42MTcgTDExMy45MDksNzYuMzk3IEMxMTMuODM2LDc2LjQzOCAxMTMuNzU2LDc2LjQ1OSAxMTMuNjc1LDc2LjQ1OSIgaWQ9IkZpbGwtMjQiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUzLjMxNiwyMS4yNzkgQzE1MC45MDMsMjEuMjc5IDE0OC40OTUsMjAuNzUxIDE0Ni42NjQsMTkuNjkzIEMxNDQuODQ2LDE4LjY0NCAxNDMuODQ0LDE3LjIzMiAxNDMuODQ0LDE1LjcxOCBDMTQzLjg0NCwxNC4xOTEgMTQ0Ljg2LDEyLjc2MyAxNDYuNzA1LDExLjY5OCBMMTU2LjE5OCw2LjA5MSBDMTU2LjMwOSw2LjAyNSAxNTYuNDUyLDYuMDYyIDE1Ni41MTgsNi4xNzMgQzE1Ni41ODMsNi4yODQgMTU2LjU0Nyw2LjQyNyAxNTYuNDM2LDYuNDkzIEwxNDYuOTQsMTIuMTAyIEMxNDUuMjQ0LDEzLjA4MSAxNDQuMzEyLDE0LjM2NSAxNDQuMzEyLDE1LjcxOCBDMTQ0LjMxMiwxNy4wNTggMTQ1LjIzL
7196DE4LjMyNiAxNDYuODk3LDE5LjI4OSBDMTUwLjQ0NiwyMS4zMzggMTU2LjI0LDIxLjMyNyAxNTkuODExLDE5LjI2NSBMMTY5LjU1OSwxMy42MzcgQzE2OS42NywxMy41NzMgMTY5LjgxMywxMy42MTEgMTY5Ljg3OCwxMy43MjMgQzE2OS45NDMsMTMuODM0IDE2OS45MDQsMTMuOTc3IDE2OS43OTMsMTQuMDQyIEwxNjAuMDQ1LDE5LjY3IEMxNTguMTg3LDIwLjc0MiAxNTUuNzQ5LDIxLjI3OSAxNTMuMzE2LDIxLjI3OSIgaWQ9IkZpbGwtMjUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3NS45OTIgTDY3Ljc2Miw0OS40ODQiIGlkPSJGaWxsLTI2IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMy42NzUsNzYuMzQyIEMxMTMuNjE1LDc2LjM0MiAxMTMuNTU1LDc2LjMyNyAxMTMuNSw3Ni4yOTUgTDY3LjU4Nyw0OS43ODcgQzY3LjQxOSw0OS42OSA2Ny4zNjIsNDkuNDc2IDY3LjQ1OSw0OS4zMDkgQzY3LjU1Niw0OS4xNDEgNjcuNzcsNDkuMDgzIDY3LjkzNyw0OS4xOCBMMTEzLjg1LDc1LjY4OCBDMTE0LjAxOCw3NS43ODUgMTE0LjA3NSw3NiAxMTMuOTc4LDc2LjE2NyBDMTEzLjkxNCw3Ni4yNzkgMTEzLjc5Niw3Ni4zNDIgMTEzLjY3NSw3Ni4zNDIiIGlkPSJGaWxsLTI3IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY3Ljc2Miw0OS40ODQgTDY3Ljc2MiwxMDMuNDg1IEM2Ny43NjIsMTA0LjU3NSA2OC41MzIsMTA1LjkwMyA2OS40ODIsMTA2LjQ1MiBMMTExLjk1NSwxMzAuOTczIEMxMTIuOTA1LDEzMS41MjIgMTEzLjY3NSwxMzEuMDgzIDExMy42NzUsMTI5Ljk5MyBMMTEzLjY3NSw3NS45OTIiIGlkPSJGaWxsLTI4IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMi43MjcsMTMxLjU2MSBDMTEyLjQzLDEzMS41NjEgMTEyLjEwNywxMzEuNDY2IDExMS43OCwxMzEuMjc2IEw2OS4zMDcsMTA2Ljc1NSBDNjguMjQ0LDEwNi4xNDIgNjcuNDEyLDEwNC43MDUgNjcuNDEyLDEwMy40ODUgTDY3LjQxMiw0OS40ODQgQzY3LjQxMiw0OS4yOSA2Ny41NjksNDkuMTM0IDY3Ljc2Miw0OS4xMzQgQzY3Ljk1Niw0OS4xMzQgNjguMTEzLDQ5LjI5IDY4LjExMyw0OS40ODQgTDY4LjExMywxMDMuNDg1IEM2OC4xMTMsMTA0LjQ0NSA2OC44MiwxMDUuNjY1IDY5LjY1NywxMDYuMTQ4IEwxMTIuMTMsMTMwLjY3IEMxMTIuNDc0LDEzMC44NjggMTEyLjc5MSwxMzAuOTEzIDExMywxMzAuNzkyIEMxMTMuMjA2LDEzMC42NzMgMTEzLjMyNSwxMzAuMzgxIDExMy4zMjUsMTI5Ljk5MyBMMTEzLjMyNSw3NS45OTIgQzExMy4zMjUsNzUuNzk4IDExMy40ODIsNzUuNjQxIDExMy42NzUsNzUuNjQxIEMxMTMuODY5LDc1LjY0MSAxMTQuMDI1LDc1Ljc5OCAxMTQuMDI1LDc1Ljk5MiBMMTE0LjAyNSwxMjkuOTkzIEMxMTQuMDI1LDEzMC42NDggMTEzLjc4NiwxMzEuMTQ3IDExMy4zNSwxMzEuMzk5IEMxMTMuMTYyLDEzMS41MDcgMTEyLjk1MiwxMzEuNTYxIDExMi43MjcsMTMxLjU2MSIgaWQ9IkZpbGwtMjkiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEyLjg2LDQwLjUxMiBDMTEyLjg2LDQwLjUxMiAxMTIuODYsNDAuNTEyIDExMi44NTksNDAuNTEyIEMxMTAuNTQxLDQwLjUxMiAxMDguMzYsMzkuOTkgMTA2LjcxNywzOS4wNDEgQzEwNS4wMTIsMzguMDU3IDEwNC4wNzQsMzYuNzI2IDEwNC4wNzQsMzUuMjkyIEMxMDQuMDc0LDMzLjg0NyAxMDUuMDI2LDMyLjUwMSAxMDYuNzU0LDMxLjUwNCBMMTE4Ljc5NSwyNC41NTEgQzEyMC40NjMsMjMuNTg5IDEyMi42NjksMjMuMDU4IDEyNS4wMDcsMjMuMDU4IEMxMjcuMzI1LDIzLjA1OCAxMjkuNTA2LDIzLjU4MSAxMzEuMTUsMjQuNTMgQzEzMi44NTQsMjUuNTE0IDEzMy43OTMsMjYuODQ1IDEzMy43OTMsMjguMjc4IEMxMzMuNzkzLDI5LjcyNCAxMzIuODQxLDMxLjA2OSAxMzEuMTEzLDMyLjA2NyBMMTE5LjA3MSwzOS4wMTkgQzExNy40MDMsMzkuOTgyIDExNS4xOTcsNDAuNTEyIDExMi44Niw0MC41MTIgTDExMi44Niw0MC41MTIgWiBNMTI1LjAwNywyMy43NTkgQzEyMi43OSwyMy43NTkgMTIwLjcwOSwyNC4yNTYgMTE5LjE0NiwyNS4xNTggTDEwNy4xMDQsMzIuMTEgQzEwNS42MDIsMzIuOTc4IDEwNC43NzQsMzQuMTA4IDEwNC43NzQsMzUuMjkyIEMxMDQuNzc0LDM2LjQ2NSAxMDUuNTg5LDM3LjU4MSAxMDcuMDY3LDM4LjQzNCBDMTA4LjYwNSwzOS4zMjMgMTEwLjY2MywzOS44MTIgMTEyLjg1OSwzOS44MTIgTDExMi44NiwzOS44MTIgQzExNS4wNzYsMzkuODEyIDExNy4xNTgsMzkuMzE1IDExOC43MjEsMzguNDEzIEwxMzAuNzYyLDMxLjQ2IEMxMzIuMjY0LDMwLjU5MyAxMzMuMDkyLDI5LjQ2MyAxMzMuMDkyLDI4LjI3OCBDMTMzLjA5MiwyNy4xMDYgMTMyLjI3OCwyNS45OSAxMzAuOCwyNS4xMzYgQzEyOS4yNjEsMjQuMjQ4IDEyNy4yMDQsMjMuNzU5IDEyNS4wMDcsMjMuNzU5IEwxMjUuMDA3LDIzLjc1OSBaIiBpZD0iRmlsbC0zMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNjUuNjMsMTYuMjE5IEwxNTkuODk2LDE5LjUzIEMxNTYuNzI5LDIxLjM1OCAxNTEuNjEsMjEuMzY3IDE0OC40NjMsMTkuNTUgQzE0NS4zMTYsMTcuNzMzIDE0NS4zMzIsMTQuNzc4IDE0OC40OTksMTIuOTQ5IEwxNTQuMjMzLDkuNjM5IEwxNjUuNjMsMTYuMjE5IiBpZD0iRmlsbC0zMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNTQuMjMzLDEwLjQ0OCBMMTY0LjIyOCwxNi4yMTkgTDE1OS41NDYsMTguOTIzIEMxNTguMTEyLDE
71965Ljc1IDE1Ni4xOTQsMjAuMjA2IDE1NC4xNDcsMjAuMjA2IEMxNTIuMTE4LDIwLjIwNiAxNTAuMjI0LDE5Ljc1NyAxNDguODE0LDE4Ljk0MyBDMTQ3LjUyNCwxOC4xOTkgMTQ2LjgxNCwxNy4yNDkgMTQ2LjgxNCwxNi4yNjkgQzE0Ni44MTQsMTUuMjc4IDE0Ny41MzcsMTQuMzE0IDE0OC44NSwxMy41NTYgTDE1NC4yMzMsMTAuNDQ4IE0xNTQuMjMzLDkuNjM5IEwxNDguNDk5LDEyLjk0OSBDMTQ1LjMzMiwxNC43NzggMTQ1LjMxNiwxNy43MzMgMTQ4LjQ2MywxOS41NSBDMTUwLjAzMSwyMC40NTUgMTUyLjA4NiwyMC45MDcgMTU0LjE0NywyMC45MDcgQzE1Ni4yMjQsMjAuOTA3IDE1OC4zMDYsMjAuNDQ3IDE1OS44OTYsMTkuNTMgTDE2NS42MywxNi4yMTkgTDE1NC4yMzMsOS42MzkiIGlkPSJGaWxsLTMyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NS40NDUsNzIuNjY3IEwxNDUuNDQ1LDcyLjY2NyBDMTQzLjY3Miw3Mi42NjcgMTQyLjIwNCw3MS44MTcgMTQxLjIwMiw3MC40MjIgQzE0MS4xMzUsNzAuMzMgMTQxLjE0NSw3MC4xNDcgMTQxLjIyNSw3MC4wNjYgQzE0MS4zMDUsNjkuOTg1IDE0MS40MzIsNjkuOTQ2IDE0MS41MjUsNzAuMDExIEMxNDIuMzA2LDcwLjU1OSAxNDMuMjMxLDcwLjgyMyAxNDQuMjc2LDcwLjgyMiBDMTQ1LjU5OCw3MC44MjIgMTQ3LjAzLDcwLjM3NiAxNDguNTMyLDY5LjUwOSBDMTUzLjg0Miw2Ni40NDMgMTU4LjE2Myw1OC45ODcgMTU4LjE2Myw1Mi44OTQgQzE1OC4xNjMsNTAuOTY3IDE1Ny43MjEsNDkuMzMyIDE1Ni44ODQsNDguMTY4IEMxNTYuODE4LDQ4LjA3NiAxNTYuODI4LDQ3Ljk0OCAxNTYuOTA4LDQ3Ljg2NyBDMTU2Ljk4OCw0Ny43ODYgMTU3LjExNCw0Ny43NzQgMTU3LjIwOCw0Ny44NCBDMTU4Ljg3OCw0OS4wMTIgMTU5Ljc5OCw1MS4yMiAxNTkuNzk4LDU0LjA1OSBDMTU5Ljc5OCw2MC4zMDEgMTU1LjM3Myw2OC4wNDYgMTQ5LjkzMyw3MS4xODYgQzE0OC4zNiw3Mi4wOTQgMTQ2Ljg1LDcyLjY2NyAxNDUuNDQ1LDcyLjY2NyBMMTQ1LjQ0NSw3Mi42NjcgWiBNMTQyLjQ3Niw3MSBDMTQzLjI5LDcxLjY1MSAxNDQuMjk2LDcyLjAwMiAxNDUuNDQ1LDcyLjAwMiBDMTQ2Ljc2Nyw3Mi4wMDIgMTQ4LjE5OCw3MS41NSAxNDkuNyw3MC42ODIgQzE1NS4wMSw2Ny42MTcgMTU5LjMzMSw2MC4xNTkgMTU5LjMzMSw1NC4wNjUgQzE1OS4zMzEsNTIuMDg1IDE1OC44NjgsNTAuNDM1IDE1OC4wMDYsNDkuMjcyIEMxNTguNDE3LDUwLjMwNyAxNTguNjMsNTEuNTMyIDE1OC42Myw1Mi44OTIgQzE1OC42Myw1OS4xMzQgMTU0LjIwNSw2Ni43NjcgMTQ4Ljc2NSw2OS45MDcgQzE0Ny4xOTIsNzAuODE2IDE0NS42ODEsNzEuMjgzIDE0NC4yNzYsNzEuMjgzIEMxNDMuNjM0LDcxLjI4MyAxNDMuMDMzLDcxLjE5MiAxNDIuNDc2LDcxIEwxNDIuNDc2LDcxIFoiIGlkPSJGaWxsLTMzIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0OC42NDgsNjkuNzA0IEMxNTQuMDMyLDY2LjU5NiAxNTguMzk2LDU5LjA2OCAxNTguMzk2LDUyLjg5MSBDMTU4LjM5Niw1MC44MzkgMTU3LjkxMyw0OS4xOTggMTU3LjA3NCw0OC4wMyBDMTU1LjI4OSw0Ni43NzggMTUyLjY5OSw0Ni44MzYgMTQ5LjgxNiw0OC41MDEgQzE0NC40MzMsNTEuNjA5IDE0MC4wNjgsNTkuMTM3IDE0MC4wNjgsNjUuMzE0IEMxNDAuMDY4LDY3LjM2NSAxNDAuNTUyLDY5LjAwNiAxNDEuMzkxLDcwLjE3NCBDMTQzLjE3Niw3MS40MjcgMTQ1Ljc2NSw3MS4zNjkgMTQ4LjY0OCw2OS43MDQiIGlkPSJGaWxsLTM0IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NC4yNzYsNzEuMjc2IEwxNDQuMjc2LDcxLjI3NiBDMTQzLjEzMyw3MS4yNzYgMTQyLjExOCw3MC45NjkgMTQxLjI1Nyw3MC4zNjUgQzE0MS4yMzYsNzAuMzUxIDE0MS4yMTcsNzAuMzMyIDE0MS4yMDIsNzAuMzExIEMxNDAuMzA3LDY5LjA2NyAxMzkuODM1LDY3LjMzOSAxMzkuODM1LDY1LjMxNCBDMTM5LjgzNSw1OS4wNzMgMTQ0LjI2LDUxLjQzOSAxNDkuNyw0OC4yOTggQzE1MS4yNzMsNDcuMzkgMTUyLjc4NCw0Ni45MjkgMTU0LjE4OSw0Ni45MjkgQzE1NS4zMzIsNDYuOTI5IDE1Ni4zNDcsNDcuMjM2IDE1Ny4yMDgsNDcuODM5IEMxNTcuMjI5LDQ3Ljg1NCAxNTcuMjQ4LDQ3Ljg3MyAxNTcuMjYzLDQ3Ljg5NCBDMTU4LjE1Nyw0OS4xMzggMTU4LjYzLDUwLjg2NSAxNTguNjMsNTIuODkxIEMxNTguNjMsNTkuMTMyIDE1NC4yMDUsNjYuNzY2IDE0OC43NjUsNjkuOTA3IEMxNDcuMTkyLDcwLjgxNSAxNDUuNjgxLDcxLjI3NiAxNDQuMjc2LDcxLjI3NiBMMTQ0LjI3Niw3MS4yNzYgWiBNMTQxLjU1OCw3MC4xMDQgQzE0Mi4zMzEsNzAuNjM3IDE0My4yNDUsNzEuMDA1IDE0NC4yNzYsNzEuMDA1IEMxNDUuNTk4LDcxLjAwNSAxNDcuMDMsNzAuNDY3IDE0OC41MzIsNjkuNiBDMTUzLjg0Miw2Ni41MzQgMTU4LjE2Myw1OS4wMzMgMTU4LjE2Myw1Mi45MzkgQzE1OC4xNjMsNTEuMDMxIDE1Ny43MjksNDkuMzg1IDE1Ni45MDcsNDguMjIzIEMxNTYuMTMzLDQ3LjY5MSAxNTUuMjE5LDQ3LjQwOSAxNTQuMTg5LDQ3LjQwOSBDMTUyLjg2Nyw0Ny40MDkgMTUxLjQzNSw0Ny44NDIgMTQ5LjkzMyw0OC43MDkgQzE0NC42MjMsNTEuNzc1IDE0MC4zMDIsNTkuMjczIDE0MC4zMDIsNjUuMzY2IEMxNDAuMzAyLDY3LjI3NiAxNDAuNzM2LDY4Ljk0MiAxNDEuNTU4LDcwLjEwNCBMMTQxLjU1OCw3MC4xMDQgWiIgaWQ9IkZpbGwtMzUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUwLjcyLDY1LjM2MSBMMTUwLjM1Nyw2NS4wNjYgQzE1MS4xNDcsNjQuMDkyIDE1MS44NjksNjMuMDQgMTUyLjUwNSw2MS45MzggQzE1My4zMTMsNjAuNTM5IDE1My45NzgsNTkuMDY3IDE1NC40ODIsNTcuNTYzIEwxNTQuOTI1LDU3LjcxMiBDMTU0LjQxMiw1OS4yNDUgMTUzLjczMyw2MC43NDUgMTUyLjkxLDYyLjE3MiBDMTUyLjI2Miw2My4yOTUgMTUxLjUyNSw2NC4zNjggMTUwLjcyLDY1LjM2MSIgaWQ9IkZpbGwtMzYiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE1LjkxNyw4NC41MTQgTDExNS41NTQsODQuMjIgQzExNi4zNDQsODMuMjQ1IDExNy4wNjYsODIuMTk0IDExNy43MDIsODEuMDkyIEMxMTguNTEsNzkuNjkyIDExOS4xNzUsNzguMjIgMTE5LjY3OCw3Ni43MTcgTDEyMC4xMjEsNzYuODY1IEMxMTkuNjA4LDc4LjM5OCAxMTguOTMsNzkuODk5IDExOC4xMDYsODEuMzI2IEMxMTcuNDU4LDgyLjQ0OCAxMTYuNzIyLDgzLjUyMSAxMTUuOTE3LDg0LjUxNCIgaWQ9IkZpbGwtMzciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE0LDEzMC40NzYgTDExNCwxMzAuMDA4IEwxMTQsNzYuMDUyIEwxMTQsNzUuNTg0IEwxMTQsNzYuMDUyIEwxMTQsMTMwLjAwOCBMMTE0LDEzMC40NzYiIGlkPSJGaWxsLTM4IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyLjAwMDAwMCwgMC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTkuODIyLDM3LjQ3NCBDMTkuODM5LDM3LjMzOSAxOS43NDcsMzcuMTk0IDE5LjU1NSwzNy4wODIgQzE5LjIyOCwzNi44OTQgMTguNzI5LDM2Ljg3MiAxOC40NDYsMzcuMDM3IEwxMi40MzQsNDAuNTA4IEMxMi4zMDMsNDAuNTg0IDEyLjI0LDQwLjY4NiAxMi4yNDMsNDAuNzkzIEMxMi4yNDUsNDAuOTI1IDEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQxLjM3MSBMMTIuMjQ1LDQxLjQxNCBMMTIuMjM4LDQxLjU0MiBDOC4xNDgsNDMuODg3IDUuNjQ3LDQ1LjMyMSA1LjY0Nyw0NS4zMjEgQzUuNjQ2LDQ1LjMyMSAzLjU3LDQ2LjM2NyAyLjg2LDUwLjUxMyBDMi44Niw1MC41MTMgMS45NDgsNTcuNDc0IDEuOTYyLDcwLjI1OCBDMS45NzcsODIuODI4IDIuNTY4LDg3LjMyOCAzLjEyOSw5MS42MDkgQzMuMzQ5LDkzLjI5MyA2LjEzLDkzLjczNCA2LjEzLDkzLjczNCBDNi40NjEsOTMuNzc0IDYuODI4LDkzLjcwNyA3LjIxLDkzLjQ4NiBMODIuNDgzLDQ5LjkzNSBDODQuMjkxLDQ4Ljg2NiA4NS4xNSw0Ni4yMTYgODUuNTM5LDQzLjY1MSBDODYuNzUyLDM1LjY2MSA4Ny4yMTQsMTAuNjczIDg1LjI2NCwzLjc3MyBDODUuMDY4LDMuMDggODQuNzU0LDIuNjkgODQuMzk2LDIuNDkxIEw4Mi4zMSwxLjcwMSBDODEuNTgzLDEuNzI5IDgwLjg5NCwyLjE2OCA4MC43NzYsMi4yMzYgQzgwLjYzNiwyLjMxNyA0MS44MDcsMjQuNTg1IDIwLjAzMiwzNy4wNzIgTDE5LjgyMiwzNy40NzQiIGlkPSJGaWxsLTEiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNODIuMzExLDEuNzAxIEw4NC4zOTYsMi40OTEgQzg0Ljc1NCwyLjY5IDg1LjA2OCwzLjA4IDg1LjI2NCwzLjc3MyBDODcuMjEzLDEwLjY3MyA4Ni43NTEsMzUuNjYgODUuNTM5LDQzLjY1MSBDODUuMTQ5LDQ2LjIxNiA4NC4yOSw0OC44NjYgODIuNDgzLDQ5LjkzNSB
7196MNy4yMSw5My40ODYgQzYuODk3LDkzLjY2NyA2LjU5NSw5My43NDQgNi4zMTQsOTMuNzQ0IEw2LjEzMSw5My43MzMgQzYuMTMxLDkzLjczNCAzLjM0OSw5My4yOTMgMy4xMjgsOTEuNjA5IEMyLjU2OCw4Ny4zMjcgMS45NzcsODIuODI4IDEuOTYzLDcwLjI1OCBDMS45NDgsNTcuNDc0IDIuODYsNTAuNTEzIDIuODYsNTAuNTEzIEMzLjU3LDQ2LjM2NyA1LjY0Nyw0NS4zMjEgNS42NDcsNDUuMzIxIEM1LjY0Nyw0NS4zMjEgOC4xNDgsNDMuODg3IDEyLjIzOCw0MS41NDIgTDEyLjI0NSw0MS40MTQgTDEyLjI0NSw0MS4zNzEgQzEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQwLjkyNSAxMi4yNDMsNDAuNzkzIEMxMi4yNCw0MC42ODYgMTIuMzAyLDQwLjU4MyAxMi40MzQsNDAuNTA4IEwxOC40NDYsMzcuMDM2IEMxOC41NzQsMzYuOTYyIDE4Ljc0NiwzNi45MjYgMTguOTI3LDM2LjkyNiBDMTkuMTQ1LDM2LjkyNiAxOS4zNzYsMzYuOTc5IDE5LjU1NCwzNy4wODIgQzE5Ljc0NywzNy4xOTQgMTkuODM5LDM3LjM0IDE5LjgyMiwzNy40NzQgTDIwLjAzMywzNy4wNzIgQzQxLjgwNiwyNC41ODUgODAuNjM2LDIuMzE4IDgwLjc3NywyLjIzNiBDODAuODk0LDIuMTY4IDgxLjU4MywxLjcyOSA4Mi4zMTEsMS43MDEgTTgyLjMxMSwwLjcwNCBMODIuMjcyLDAuNzA1IEM4MS42NTQsMC43MjggODAuOTg5LDAuOTQ5IDgwLjI5OCwxLjM2MSBMODAuMjc3LDEuMzczIEM4MC4xMjksMS40NTggNTkuNzY4LDEzLjEzNSAxOS43NTgsMzYuMDc5IEMxOS41LDM1Ljk4MSAxOS4yMTQsMzUuOTI5IDE4LjkyNywzNS45MjkgQzE4LjU2MiwzNS45MjkgMTguMjIzLDM2LjAxMyAxNy45NDcsMzYuMTczIEwxMS45MzUsMzkuNjQ0IEMxMS40OTMsMzkuODk5IDExLjIzNiw0MC4zMzQgMTEuMjQ2LDQwLjgxIEwxMS4yNDcsNDAuOTYgTDUuMTY3LDQ0LjQ0NyBDNC43OTQsNDQuNjQ2IDIuNjI1LDQ1Ljk3OCAxLjg3Nyw1MC4zNDUgTDEuODcxLDUwLjM4NCBDMS44NjIsNTAuNDU0IDAuOTUxLDU3LjU1NyAwLjk2NSw3MC4yNTkgQzAuOTc5LDgyLjg3OSAxLjU2OCw4Ny4zNzUgMi4xMzcsOTEuNzI0IEwyLjEzOSw5MS43MzkgQzIuNDQ3LDk0LjA5NCA1LjYxNCw5NC42NjIgNS45NzUsOTQuNzE5IEw2LjAwOSw5NC43MjMgQzYuMTEsOTQuNzM2IDYuMjEzLDk0Ljc0MiA2LjMxNCw5NC43NDIgQzYuNzksOTQuNzQyIDcuMjYsOTQuNjEgNy43MSw5NC4zNSBMODIuOTgzLDUwLjc5OCBDODQuNzk0LDQ5LjcyNyA4NS45ODIsNDcuMzc1IDg2LjUyNSw0My44MDEgQzg3LjcxMSwzNS45ODcgODguMjU5LDEwLjcwNSA4Ni4yMjQsMy41MDIgQzg1Ljk3MSwyLjYwOSA4NS41MiwxLjk3NSA4NC44ODEsMS42MiBMODQuNzQ5LDEuNTU4IEw4Mi42NjQsMC43NjkgQzgyLjU1MSwwLjcyNSA4Mi40MzEsMC43MDQgODIuMzExLDAuNzA0IiBpZD0iRmlsbC0yIiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY2LjI2NywxMS41NjUgTDY3Ljc2MiwxMS45OTkgTDExLjQyMyw0NC4zMjUiIGlkPSJGaWxsLTMiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMjAyLDkwLjU0NSBDMTIuMDI5LDkwLjU0NSAxMS44NjIsOTAuNDU1IDExLjc2OSw5MC4yOTUgQzExLjYzMiw5MC4wNTcgMTEuNzEzLDg5Ljc1MiAxMS45NTIsODkuNjE0IEwzMC4zODksNzguOTY5IEMzMC42MjgsNzguODMxIDMwLjkzMyw3OC45MTMgMzEuMDcxLDc5LjE1MiBDMzEuMjA4LDc5LjM5IDMxLjEyNyw3OS42OTYgMzAuODg4LDc5LjgzMyBMMTIuNDUxLDkwLjQ3OCBMMTIuMjAyLDkwLjU0NSIgaWQ9IkZpbGwtNCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43NjQsNDIuNjU0IEwxMy42NTYsNDIuNTkyIEwxMy43MDIsNDIuNDIxIEwxOC44MzcsMzkuNDU3IEwxOS4wMDcsMzkuNTAyIEwxOC45NjIsMzkuNjczIEwxMy44MjcsNDIuNjM3IEwxMy43NjQsNDIuNjU0IiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTguNTIsOTAuMzc1IEw4LjUyLDQ2LjQyMSBMOC41ODMsNDYuMzg1IEw3NS44NCw3LjU1NCBMNzUuODQsNTEuNTA4IEw3NS43NzgsNTEuNTQ0IEw4LjUyLDkwLjM3NSBMOC41Miw5MC4zNzUgWiBNOC43Nyw0Ni41NjQgTDguNzcsODkuOTQ0IEw3NS41OTEsNTEuMzY1IEw3NS41OTEsNy45ODUgTDguNzcsNDYuNTY0IEw4Ljc3LDQ2LjU2NCBaIiBpZD0iRmlsbC02IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTI0Ljk4Niw4My4xODIgQzI0Ljc1Niw4My4zMzEgMjQuMzc0LDgzLjU2NiAyNC4xMzcsODMuNzA1IEwxMi42MzIsOTAuNDA2IEMxMi4zOTUsOTAuNTQ1IDEyLjQyNiw5MC42NTggMTIuNyw5MC42NTggTDEzLjI2NSw5MC42NTggQzEzLjU0LDkwLjY1OCAxMy45NTgsOTAuNTQ1IDE0LjE5NSw5MC40MDYgTDI1LjcsODMuNzA1IEMyNS45MzcsODMuNTY2IDI2LjEyOCw4My40NTIgMjYuMTI1LDgzLjQ0OSBDMjYuMTIyLDgzLjQ0NyAyNi4xMTksODMuMjIgMjYuMTE5LDgyLjk0NiBDMjYuMTE5LDgyLjY3MiAyNS45MzEsODIuNTY5IDI1LjcwMSw4Mi43MTkgTDI0Ljk4Niw4My4xODIiIGlkPSJGaWxsLTciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTMuMjY2LDkwLjc4MiBMMTIuNyw5MC43ODIgQzEyLjUsOTAuNzgyIDEyLjM4NCw5MC43MjYgMTIuMzU0LDkwLjYxNiBDMTIuMzI0LDkwLjUwNiAxMi4zOTcsOTAuMzk5IDEyLjU2OSw5MC4yOTkgTDI0LjA3NCw4My41OTcgQzI0LjMxLDgzLjQ1OSAyNC42ODksODMuMjI2IDI0LjkxOCw4My4wNzggTDI1LjYzMyw4Mi42MTQgQzI1LjcyMyw4Mi41NTUgMjUuODEzLDgyLjUyNSAyNS44OTksODIuNTI1IEMyNi4wNzEsODIuNTI1IDI2LjI0NCw4Mi42NTUgMjYuMjQ0LDgyLjk0NiBDMjYuMjQ0LDgzLjE2IDI2LjI0NSw4My4zMDkgMjYuMjQ3LDgzLjM4MyBMMjYuMjUzLDgzLjM4NyBMMjYuMjQ5LDgzLjQ1NiBDMjYuMjQ2LDgzLjUzMSAyNi4yNDYsODMuNTMxIDI1Ljc2Myw4My44MTIgTDE0LjI1OCw5MC41MTQgQzE0LDkwLjY2NSAxMy41NjQsOTAuNzgyIDEzLjI2Niw5MC43ODIgTDEzLjI2Niw5MC43ODIgWiBNMTIuNjY2LDkwLjUzMiBMMTIuNyw5MC41MzMgTDEzLjI2Niw5MC41MzMgQzEzLjUxOCw5MC41MzMgMTMuOTE1LDkwLjQyNSAxNC4xMzIsOTAuMjk5IEwyNS42MzcsODMuNTk3IEMyNS44MDUsODMuNDk5IDI1LjkzMSw4My40MjQgMjUuOTk4LDgzLjM4MyBDMjUuOTk0LDgzLjI5OSAyNS45OTQsODMuMTY1IDI1Ljk5NCw4Mi45NDYgTDI1Ljg5OSw4Mi43NzUgTDI1Ljc2OCw4Mi44MjQgTDI1LjA1NCw4My4yODcgQzI0LjgyMiw4My40MzcgMjQuNDM4LDgzLjY3MyAyNC4yLDgzLjgxMiBMMTIuNjk1LDkwLjUxNCBMMTIuNjY2LDkwLjUzMiBMMTIuNjY2LDkwLjUzMiBaIiBpZD0iRmlsbC04IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEzLjI2Niw4OS44NzEgTDEyLjcsODkuODcxIEMxMi41LDg5Ljg3MSAxMi4zODQsODkuODE1IDEyLjM1NCw4OS43MDUgQzEyLjMyNCw4OS41OTUgMTIuMzk3LDg5LjQ4OCAxMi41NjksODkuMzg4IEwyNC4wNzQsODIuNjg2IEMyNC4zMzIsODIuNTM1IDI0Ljc2OCw4Mi40MTggMjUuMDY3LDgyLjQxOCBMMjUuNjMyLDgyLjQxOCBDMjUuODMyLDgyLjQxOCAyNS45NDgsODIuNDc0IDI1Ljk3OCw4Mi41ODQgQzI2LjAwOCw4Mi42OTQgMjUuOTM1LDgyLjgwMSAyNS43NjMsODIuOTAxIEwxNC4yNTgsODkuNjAzIEMxNCw4OS43NTQgMTMuNTY0LDg5Ljg3MSAxMy4yNjYsODkuODcxIEwxMy4yNjYsODkuODcxIFogTTEyLjY2Niw4OS42MjEgTDEyLjcsODkuNjIyIEwxMy4yNjYsODkuNjIyIEMxMy41MTgsODkuNjIyIDEzLjkxNSw4OS41MTUgMTQuMTMyLDg5LjM4OCBMMjUuNjM3LDgyLjY4NiB
7196MMjUuNjY3LDgyLjY2OCBMMjUuNjMyLDgyLjY2NyBMMjUuMDY3LDgyLjY2NyBDMjQuODE1LDgyLjY2NyAyNC40MTgsODIuNzc1IDI0LjIsODIuOTAxIEwxMi42OTUsODkuNjAzIEwxMi42NjYsODkuNjIxIEwxMi42NjYsODkuNjIxIFoiIGlkPSJGaWxsLTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMzcsOTAuODAxIEwxMi4zNyw4OS41NTQgTDEyLjM3LDkwLjgwMSIgaWQ9IkZpbGwtMTAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNi4xMyw5My45MDEgQzUuMzc5LDkzLjgwOCA0LjgxNiw5My4xNjQgNC42OTEsOTIuNTI1IEMzLjg2LDg4LjI4NyAzLjU0LDgzLjc0MyAzLjUyNiw3MS4xNzMgQzMuNTExLDU4LjM4OSA0LjQyMyw1MS40MjggNC40MjMsNTEuNDI4IEM1LjEzNCw0Ny4yODIgNy4yMSw0Ni4yMzYgNy4yMSw0Ni4yMzYgQzcuMjEsNDYuMjM2IDgxLjY2NywzLjI1IDgyLjA2OSwzLjAxNyBDODIuMjkyLDIuODg4IDg0LjU1NiwxLjQzMyA4NS4yNjQsMy45NCBDODcuMjE0LDEwLjg0IDg2Ljc1MiwzNS44MjcgODUuNTM5LDQzLjgxOCBDODUuMTUsNDYuMzgzIDg0LjI5MSw0OS4wMzMgODIuNDgzLDUwLjEwMSBMNy4yMSw5My42NTMgQzYuODI4LDkzLjg3NCA2LjQ2MSw5My45NDEgNi4xMyw5My45MDEgQzYuMTMsOTMuOTAxIDMuMzQ5LDkzLjQ2IDMuMTI5LDkxLjc3NiBDMi41NjgsODcuNDk1IDEuOTc3LDgyLjk5NSAxLjk2Miw3MC40MjUgQzEuOTQ4LDU3LjY0MSAyLjg2LDUwLjY4IDIuODYsNTAuNjggQzMuNTcsNDYuNTM0IDUuNjQ3LDQ1LjQ4OSA1LjY0Nyw0NS40ODkgQzUuNjQ2LDQ1LjQ4OSA4LjA2NSw0NC4wOTIgMTIuMjQ1LDQxLjY3OSBMMTMuMTE2LDQxLjU2IEwxOS43MTUsMzcuNzMgTDE5Ljc2MSwzNy4yNjkgTDYuMTMsOTMuOTAxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjMxNyw5NC4xNjEgTDYuMTAyLDk0LjE0OCBMNi4xMDEsOTQuMTQ4IEw1Ljg1Nyw5NC4xMDEgQzUuMTM4LDkzLjk0NSAzLjA4NSw5My4zNjUgMi44ODEsOTEuODA5IEMyLjMxMyw4Ny40NjkgMS43MjcsODIuOTk2IDEuNzEzLDcwLjQyNSBDMS42OTksNTcuNzcxIDIuNjA0LDUwLjcxOCAyLjYxMyw1MC42NDggQzMuMzM4LDQ2LjQxNyA1LjQ0NSw0NS4zMSA1LjUzNSw0NS4yNjYgTDEyLjE2Myw0MS40MzkgTDEzLjAzMyw0MS4zMiBMMTkuNDc5LDM3LjU3OCBMMTkuNTEzLDM3LjI0NCBDMTkuNTI2LDM3LjEwNyAxOS42NDcsMzcuMDA4IDE5Ljc4NiwzNy4wMjEgQzE5LjkyMiwzNy4wMzQgMjAuMDIzLDM3LjE1NiAyMC4wMDksMzcuMjkzIEwxOS45NSwzNy44ODIgTDEzLjE5OCw0MS44MDEgTDEyLjMyOCw0MS45MTkgTDUuNzcyLDQ1LjcwNCBDNS43NDEsNDUuNzIgMy43ODIsNDYuNzcyIDMuMTA2LDUwLjcyMiBDMy4wOTksNTAuNzgyIDIuMTk4LDU3LjgwOCAyLjIxMiw3MC40MjQgQzIuMjI2LDgyLjk2MyAyLjgwOSw4Ny40MiAzLjM3Myw5MS43MjkgQzMuNDY0LDkyLjQyIDQuMDYyLDkyLjg4MyA0LjY4Miw5My4xODEgQzQuNTY2LDkyLjk4NCA0LjQ4Niw5Mi43NzYgNC40NDYsOTIuNTcyIEMzLjY2NSw4OC41ODggMy4yOTEsODQuMzcgMy4yNzYsNzEuMTczIEMzLjI2Miw1OC41MiA0LjE2Nyw1MS40NjYgNC4xNzYsNTEuMzk2IEM0LjkwMSw0Ny4xNjUgNy4wMDgsNDYuMDU5IDcuMDk4LDQ2LjAxNCBDNy4wOTQsNDYuMDE1IDgxLjU0MiwzLjAzNCA4MS45NDQsMi44MDIgTDgxLjk3MiwyLjc4NSBDODIuODc2LDIuMjQ3IDgzLjY5MiwyLjA5NyA4NC4zMzIsMi4zNTIgQzg0Ljg4NywyLjU3MyA4NS4yODEsMy4wODUgODUuNTA0LDMuODcyIEM4Ny41MTgsMTEgODYuOTY0LDM2LjA5MSA4NS43ODUsNDMuODU1IEM4NS4yNzgsNDcuMTk2IDg0LjIxLDQ5LjM3IDgyLjYxLDUwLjMxNyBMNy4zMzUsOTMuODY5IEM2Ljk5OSw5NC4wNjMgNi42NTgsOTQuMTYxIDYuMzE3LDk0LjE2MSBMNi4zMTcsOTQuMTYxIFogTTYuMTcsOTMuNjU0IEM2LjQ2Myw5My42OSA2Ljc3NCw5My42MTcgNy4wODUsOTMuNDM3IEw4Mi4zNTgsNDkuODg2IEM4NC4xODEsNDguODA4IDg0Ljk2LDQ1Ljk3MSA4NS4yOTIsNDMuNzggQzg2LjQ2NiwzNi4wNDkgODcuMDIzLDExLjA4NSA4NS4wMjQsNC4wMDggQzg0Ljg0NiwzLjM3NyA4NC41NTEsMi45NzYgODQuMTQ4LDIuODE2IEM4My42NjQsMi42MjMgODIuOTgyLDIuNzY0IDgyLjIyNywzLjIxMyBMODIuMTkzLDMuMjM0IEM4MS43OTEsMy40NjYgNy4zMzUsNDYuNDUyIDcuMzM1LDQ2LjQ1MiBDNy4zMDQsNDYuNDY5IDUuMzQ2LDQ3LjUyMSA0LjY2OSw1MS40NzEgQzQuNjYyLDUxLjUzIDMuNzYxLDU4LjU1NiAzLjc3NSw3MS4xNzMgQzMuNzksODQuMzI4IDQuMTYxLDg4LjUyNCA0LjkzNiw5Mi40NzYgQzUuMDI2LDkyLjkzNyA1LjQxMiw5My40NTkgNS45NzMsOTMuNjE1IEM2LjA4Nyw5My42NCA2LjE1OCw5My42NTIgNi4xNjksOTMuNjU0IEw2LjE3LDkzLjY1NCBMNi4xNyw5My42NTQgWiIgaWQ9IkZpbGwtMTIiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4zMTcsNjguOTgyIEM3LjgwNiw2OC43MDEgOC4yMDIsNjguOTI2IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNi44MjksNzEuMjk0IDYuNDMzLDcxLjA2OSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIiBpZD0iRmlsbC0xMyIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjkyLDcxLjEzMyBDNi42MzEsNzEuMTMzIDYuNDMzLDcwLjkwNSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIEM3LjQ2LDY4LjkgNy41OTUsNjguODYxIDcuNzE0LDY4Ljg2MSBDOC4wMDMsNjguODYxIDguMjAyLDY5LjA5IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNy4xNzQsNzEuMDk0IDcuMDM5LDcxLjEzMyA2LjkyLDcxLjEzMyBNNy43MTQsNjguNjc0IEM3LjU1Nyw2OC42NzQgNy4zOTIsNjguNzIzIDcuMjI0LDY4LjgyMSBDNi42NzYsNjkuMTM4IDYuMjQ2L
7196DY5Ljg3OSA2LjI0Niw3MC41MDggQzYuMjQ2LDcwLjk5NCA2LjUxNyw3MS4zMiA2LjkyLDcxLjMyIEM3LjA3OCw3MS4zMiA3LjI0Myw3MS4yNzEgNy40MTEsNzEuMTc0IEM3Ljk1OSw3MC44NTcgOC4zODksNzAuMTE3IDguMzg5LDY5LjQ4NyBDOC4zODksNjkuMDAxIDguMTE3LDY4LjY3NCA3LjcxNCw2OC42NzQiIGlkPSJGaWxsLTE0IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYuOTIsNzAuOTQ3IEM2LjY0OSw3MC45NDcgNi42MjEsNzAuNjQgNi42MjEsNzAuNTA4IEM2LjYyMSw3MC4wMTcgNi45ODIsNjkuMzkyIDcuNDExLDY5LjE0NSBDNy41MjEsNjkuMDgyIDcuNjI1LDY5LjA0OSA3LjcxNCw2OS4wNDkgQzcuOTg2LDY5LjA0OSA4LjAxNSw2OS4zNTUgOC4wMTUsNjkuNDg3IEM4LjAxNSw2OS45NzggNy42NTIsNzAuNjAzIDcuMjI0LDcwLjg1MSBDNy4xMTUsNzAuOTE0IDcuMDEsNzAuOTQ3IDYuOTIsNzAuOTQ3IE03LjcxNCw2OC44NjEgQzcuNTk1LDY4Ljg2MSA3LjQ2LDY4LjkgNy4zMTcsNjguOTgyIEM2LjgyOSw2OS4yNjUgNi40MzMsNjkuOTQ4IDYuNDMzLDcwLjUwOCBDNi40MzMsNzAuOTA1IDYuNjMxLDcxLjEzMyA2LjkyLDcxLjEzMyBDNy4wMzksNzEuMTMzIDcuMTc0LDcxLjA5NCA3LjMxNyw3MS4wMTIgQzcuODA2LDcwLjczIDguMjAyLDcwLjA0NyA4LjIwMiw2OS40ODcgQzguMjAyLDY5LjA5IDguMDAzLDY4Ljg2MSA3LjcxNCw2OC44NjEiIGlkPSJGaWxsLTE1IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTcuNDQ0LDg1LjM1IEM3LjcwOCw4NS4xOTggNy45MjEsODUuMzE5IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuOTI1IDcuNzA4LDg2LjI5MiA3LjQ0NCw4Ni40NDQgQzcuMTgxLDg2LjU5NyA2Ljk2Nyw4Ni40NzUgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IiBpZD0iRmlsbC0xNiIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik03LjIzLDg2LjUxIEM3LjA3NCw4Ni41MSA2Ljk2Nyw4Ni4zODcgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IEM3LjUyMSw4NS4zMDUgNy41OTQsODUuMjg0IDcuNjU4LDg1LjI4NCBDNy44MTQsODUuMjg0IDcuOTIxLDg1LjQwOCA3LjkyMSw4NS42MjIgQzcuOTIxLDg1LjkyNSA3LjcwOCw4Ni4yOTIgNy40NDQsODYuNDQ0IEM3LjM2Nyw4Ni40ODkgNy4yOTQsODYuNTEgNy4yMyw4Ni41MSBNNy42NTgsODUuMDk4IEM3LjU1OCw4NS4wOTggNy40NTUsODUuMTI3IDcuMzUxLDg1LjE4OCBDNy4wMzEsODUuMzczIDYuNzgxLDg1LjgwNiA2Ljc4MSw4Ni4xNzMgQzYuNzgxLDg2LjQ4MiA2Ljk2Niw4Ni42OTcgNy4yMyw4Ni42OTcgQzcuMzMsODYuNjk3IDcuNDMzLDg2LjY2NiA3LjUzOCw4Ni42MDcgQzcuODU4LDg2LjQyMiA4LjEwOCw4NS45ODkgOC4xMDgsODUuNjIyIEM4LjEwOCw4NS4zMTMgNy45MjMsODUuMDk4IDcuNjU4LDg1LjA5OCIgaWQ9IkZpbGwtMTciIGZpbGw9IiM4MDk3QTIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4yMyw4Ni4zMjIgTDcuMTU0LDg2LjE3MyBDNy4xNTQsODUuOTM4IDcuMzMzLDg1LjYyOSA3LjUzOCw4NS41MTIgTDcuNjU4LDg1LjQ3MSBMNy43MzQsODUuNjIyIEM3LjczNCw4NS44NTYgNy41NTUsODYuMTY0IDcuMzUxLDg2LjI4MiBMNy4yMyw4Ni4zMjIgTTcuNjU4LDg1LjI4NCBDNy41OTQsODUuMjg0IDcuNTIxLDg1LjMwNSA3LjQ0NCw4NS4zNSBDNy4xODEsODUuNTAyIDYuOTY3LDg1Ljg3MSA2Ljk2Nyw4Ni4xNzMgQzYuOTY3LDg2LjM4NyA3LjA3NCw4Ni41MSA3LjIzLDg2LjUxIEM3LjI5NCw4Ni41MSA3LjM2Nyw4Ni40ODkgNy40NDQsODYuNDQ0IEM3LjcwOCw4Ni4yOTIgNy45MjEsODUuOTI1IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuNDA4IDcuODE0LDg1LjI4NCA3LjY1OCw4NS4yODQiIGlkPSJGaWxsLTE4IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTc3LjI3OCw3Ljc2OSBMNzcuMjc4LDUxLjQzNiBMMTAuMjA4LDkwLjE2IEwxMC4yMDgsNDYuNDkzIEw3Ny4yNzgsNy43NjkiIGlkPSJGaWxsLTE5IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLjA4Myw5MC4zNzUgTDEwLjA4Myw0Ni40MjEgTDEwLjE0Niw0Ni4zODUgTDc3LjQwMyw3LjU1NCBMNzcuNDAzLDUxLjUwOCBMNzcuMzQxLDUxLjU0NCBMMTAuMDgzLDkwLjM3NSBMMTAuMDgzLDkwLjM3NSBaIE0xMC4zMzMsNDYuNTY0IEwxMC4zMzMsODkuOTQ0IEw3Ny4xNTQsNTEuMzY1IEw3Ny4xNTQsNy45ODUgTDEwLjMzMyw0Ni41NjQgTDEwLjMzMyw0Ni41NjQgWiIgaWQ9IkZpbGwtMjAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMjUuNzM3LDg4LjY0NyBMMTE4LjA5OCw5MS45ODEgTDExOC4wOTgsODQgTDEwNi42MzksODguNzEzIEwxMDYuNjM5LDk2Ljk4MiBMOTksMTAwLjMxNSBMMTEyLjM2OSwxMDMuOTYxIEwxMjUuNzM3LDg4LjY0NyIgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTIiIGZpbGw9IiM0NTVBNjQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'; 7197 function RotateInstructions() { 7198 this.loadIcon_(); 7199 var overlay = document.createElement('div'); 7200 var s = overlay.style; 7201 s.position = 'fixed'; 7202 s.top = 0; 7203 s.right = 0; 7204 s.bottom = 0; 7205 s.left = 0; 7206 s.backgroundColor = 'gray'; 7207 s.fontFamily = 'sans-serif'; 7208 s.zIndex = 1000000; 7209 var img = document.createElement('img'); 7210 img.src = this.icon; 7211 var s = img.style; 7212 s.marginLeft = '25%'; 7213 s.marginTop = '25%'; 7214 s.width = '50%'; 7215 overlay.appendChild(img); 7216 var text = document.createElement('div'); 7217 var s = text.style; 7218 s.textAlign = 'center'; 7219 s.fontSize = '16px'; 7220 s.lineHeight = '24px'; 7221 s.margin = '24px 25%'; 7222 s.width = '50%'; 7223 text.innerHTML = 'Place your phone into your Cardboard viewer.'; 7224 overlay.appendChild(text); 7225 var snackbar = document.createElement('div'); 7226 var s = snackbar.style; 7227 s.backgroundColor = '#CFD8DC'; 7228 s.position = 'fixed'; 7229 s.bottom = 0; 7230 s.width = '100%'; 7231 s.height = '48px'; 7232 s.padding = '14px 24px'; 7233 s.boxSizing = 'border-box'; 7234 s.color = '#656A6B'; 7235 overlay.appendChild(snackbar); 7236 var snackbarText = document.createElement('div'); 7237 snackbarText.style.float = 'left'; 7238 snackbarText.innerHTML = 'No Cardboard viewer?'; 7239 var snackbarButton = document.createElement('a'); 7240 snackbarButton.href = 'https://www.google.com/get/cardboard/get-cardboard/'; 7241 snackbarButton.innerHTML = 'get one'; 7242 snackbarButton.target = '_blank'; 7243 var s = snackbarButton.style; 7244 s.float = 'right'; 7245 s.fontWeight = 600; 7246 s.textTransform = 'uppercase'; 7247 s.borderLeft = '1px solid gray'; 7248 s.paddingLeft = '24px';
vendor: 4,328 bytes, lines 7249-7384
7249 s.textDecoration = 'none'; 7250 s.color = '#656A6B'; 7251 snackbar.appendChild(snackbarText); 7252 snackbar.appendChild(snackbarButton); 7253 this.overlay = overlay; 7254 this.text = text; 7255 this.hide(); 7256 } 7257 RotateInstructions.prototype.show = function (parent) { 7258 if (!parent && !this.overlay.parentElement) { 7259 document.body.appendChild(this.overlay); 7260 } else if (parent) { 7261 if (this.overlay.parentElement && this.overlay.parentElement != parent) this.overlay.parentElement.removeChild(this.overlay); 7262 parent.appendChild(this.overlay); 7263 } 7264 this.overlay.style.display = 'block'; 7265 var img = this.overlay.querySelector('img'); 7266 var s = img.style; 7267 if (isLandscapeMode()) { 7268 s.width = '20%'; 7269 s.marginLeft = '40%'; 7270 s.marginTop = '3%'; 7271 } else { 7272 s.width = '50%'; 7273 s.marginLeft = '25%'; 7274 s.marginTop = '25%'; 7275 } 7276 }; 7277 RotateInstructions.prototype.hide = function () { 7278 this.overlay.style.display = 'none'; 7279 }; 7280 RotateInstructions.prototype.showTemporarily = function (ms, parent) { 7281 this.show(parent); 7282 this.timer = setTimeout(this.hide.bind(this), ms); 7283 }; 7284 RotateInstructions.prototype.disableShowTemporarily = function () { 7285 clearTimeout(this.timer); 7286 }; 7287 RotateInstructions.prototype.update = function () { 7288 this.disableShowTemporarily(); 7289 if (!isLandscapeMode() && isMobile()) { 7290 this.show(); 7291 } else { 7292 this.hide(); 7293 } 7294 }; 7295 RotateInstructions.prototype.loadIcon_ = function () { 7296 this.icon = base64('image/svg+xml', rotateInstructionsAsset); 7297 }; 7298 var DEFAULT_VIEWER = 'CardboardV1'; 7299 var VIEWER_KEY = 'WEBVR_CARDBOARD_VIEWER'; 7300 var CLASS_NAME = 'webvr-polyfill-viewer-selector'; 7301 function ViewerSelector(defaultViewer) { 7302 try { 7303 this.selectedKey = localStorage.getItem(VIEWER_KEY); 7304 } catch (error) { 7305 console.error('Failed to load viewer profile: %s', error); 7306 } 7307 if (!this.selectedKey) { 7308 this.selectedKey = defaultViewer || DEFAULT_VIEWER; 7309 } 7310 this.dialog = this.createDialog_(DeviceInfo.Viewers); 7311 this.root = null; 7312 this.onChangeCallbacks_ = []; 7313 } 7314 ViewerSelector.prototype.show = function (root) { 7315 this.root = root; 7316 root.appendChild(this.dialog); 7317 var selected = this.dialog.querySelector('#' + this.selectedKey); 7318 selected.checked = true; 7319 this.dialog.style.display = 'block'; 7320 }; 7321 ViewerSelector.prototype.hide = function () { 7322 if (this.root && this.root.contains(this.dialog)) { 7323 this.root.removeChild(this.dialog); 7324 } 7325 this.dialog.style.display = 'none'; 7326 }; 7327 ViewerSelector.prototype.getCurrentViewer = function () { 7328 return DeviceInfo.Viewers[this.selectedKey]; 7329 }; 7330 ViewerSelector.prototype.getSelectedKey_ = function () { 7331 var input = this.dialog.querySelector('input[name=field]:checked'); 7332 if (input) { 7333 return input.id; 7334 } 7335 return null; 7336 }; 7337 ViewerSelector.prototype.onChange = function (cb) { 7338 this.onChangeCallbacks_.push(cb); 7339 }; 7340 ViewerSelector.prototype.fireOnChange_ = function (viewer) { 7341 for (var i = 0; i < this.onChangeCallbacks_.length; i++) { 7342 this.onChangeCallbacks_[i](viewer); 7343 } 7344 }; 7345 ViewerSelector.prototype.onSave_ = function () { 7346 this.selectedKey = this.getSelectedKey_(); 7347 if (!this.selectedKey || !DeviceInfo.Viewers[this.selectedKey]) { 7348 console.error('ViewerSelector.onSave_: this should never happen!'); 7349 return; 7350 } 7351 this.fireOnChange_(DeviceInfo.Viewers[this.selectedKey]); 7352 try { 7353 localStorage.setItem(VIEWER_KEY, this.selectedKey); 7354 } catch (error) { 7355 console.error('Failed to save viewer profile: %s', error); 7356 } 7357 this.hide(); 7358 }; 7359 ViewerSelector.prototype.createDialog_ = function (options) { 7360 var container = document.createElement('div'); 7361 container.classList.add(CLASS_NAME); 7362 container.style.display = 'none'; 7363 var overlay = document.createElement('div'); 7364 var s = overlay.style; 7365 s.position = 'fixed'; 7366 s.left = 0; 7367 s.top = 0; 7368 s.width = '100%'; 7369 s.height = '100%'; 7370 s.background = 'rgba(0, 0, 0, 0.3)'; 7371 overlay.addEventListener('click', this.hide.bind(this)); 7372 var width = 280; 7373 var dialog = document.createElement('div'); 7374 var s = dialog.style; 7375 s.boxSizing = 'border-box'; 7376 s.position = 'fixed'; 7377 s.top = '24px'; 7378 s.left = '50%'; 7379 s.marginLeft = -width / 2 + 'px'; 7380 s.width = width + 'px'; 7381 s.padding = '24px'; 7382 s.overflow = 'hidden'; 7383 s.background = '#fafafa'; 7384 s.fontFamily = "'Roboto', sans-serif";
vendor: 8,869 bytes, lines 7385-7540
7385 s.boxShadow = '0px 5px 20px #666'; 7386 dialog.appendChild(this.createH1_('Select your viewer')); 7387 for (var id in options) { 7388 dialog.appendChild(this.createChoice_(id, options[id].label)); 7389 } 7390 dialog.appendChild(this.createButton_('Save', this.onSave_.bind(this))); 7391 container.appendChild(overlay); 7392 container.appendChild(dialog); 7393 return container; 7394 }; 7395 ViewerSelector.prototype.createH1_ = function (name) { 7396 var h1 = document.createElement('h1'); 7397 var s = h1.style; 7398 s.color = 'black'; 7399 s.fontSize = '20px'; 7400 s.fontWeight = 'bold'; 7401 s.marginTop = 0; 7402 s.marginBottom = '24px'; 7403 h1.innerHTML = name; 7404 return h1; 7405 }; 7406 ViewerSelector.prototype.createChoice_ = function (id, name) { 7407 var div = document.createElement('div'); 7408 div.style.marginTop = '8px'; 7409 div.style.color = 'black'; 7410 var input = document.createElement('input'); 7411 input.style.fontSize = '30px'; 7412 input.setAttribute('id', id); 7413 input.setAttribute('type', 'radio'); 7414 input.setAttribute('value', id); 7415 input.setAttribute('name', 'field'); 7416 var label = document.createElement('label'); 7417 label.style.marginLeft = '4px'; 7418 label.setAttribute('for', id); 7419 label.innerHTML = name; 7420 div.appendChild(input); 7421 div.appendChild(label); 7422 return div; 7423 }; 7424 ViewerSelector.prototype.createButton_ = function (label, onclick) { 7425 var button = document.createElement('button'); 7426 button.innerHTML = label; 7427 var s = button.style; 7428 s.float = 'right'; 7429 s.textTransform = 'uppercase'; 7430 s.color = '#1094f7'; 7431 s.fontSize = '14px'; 7432 s.letterSpacing = 0; 7433 s.border = 0; 7434 s.background = 'none'; 7435 s.marginTop = '16px'; 7436 button.addEventListener('click', onclick); 7437 return button; 7438 }; 7439 var commonjsGlobal$$1 = typeof window !== 'undefined' ? window : typeof commonjsGlobal$1 !== 'undefined' ? commonjsGlobal$1 : typeof self !== 'undefined' ? self : {}; 7440 function unwrapExports$$1 (x) { 7441 return x && x.__esModule ? x['default'] : x; 7442 } 7443 function createCommonjsModule$$1(fn, module) { 7444 return module = { exports: {} }, fn(module, module.exports), module.exports; 7445 } 7446 var NoSleep = createCommonjsModule$$1(function (module, exports) { 7447 (function webpackUniversalModuleDefinition(root, factory) { 7448 module.exports = factory(); 7449 })(commonjsGlobal$$1, function() { 7450 return (function(modules) { 7451 var installedModules = {}; 7452 function __webpack_require__(moduleId) { 7453 if(installedModules[moduleId]) { 7454 return installedModules[moduleId].exports; 7455 } 7456 var module = installedModules[moduleId] = { 7457 i: moduleId, 7458 l: false, 7459 exports: {} 7460 }; 7461 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 7462 module.l = true; 7463 return module.exports; 7464 } 7465 __webpack_require__.m = modules; 7466 __webpack_require__.c = installedModules; 7467 __webpack_require__.d = function(exports, name, getter) { 7468 if(!__webpack_require__.o(exports, name)) { 7469 Object.defineProperty(exports, name, { 7470 configurable: false, 7471 enumerable: true, 7472 get: getter 7473 }); 7474 } 7475 }; 7476 __webpack_require__.n = function(module) { 7477 var getter = module && module.__esModule ? 7478 function getDefault() { return module['default']; } : 7479 function getModuleExports() { return module; }; 7480 __webpack_require__.d(getter, 'a', getter); 7481 return getter; 7482 }; 7483 __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 7484 __webpack_require__.p = ""; 7485 return __webpack_require__(__webpack_require__.s = 0); 7486 }) 7487 ([ 7488 (function(module, exports, __webpack_require__) { 7489 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 7490 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7491 var mediaFile = __webpack_require__(1); 7492 var oldIOS = typeof navigator !== 'undefined' && parseFloat(('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1]).replace('undefined', '3_2').replace('_', '.').replace('_', '')) < 10 && !window.MSStream; 7493 var NoSleep = function () { 7494 function NoSleep() { 7495 _classCallCheck(this, NoSleep); 7496 if (oldIOS) { 7497 this.noSleepTimer = null; 7498 } else { 7499 this.noSleepVideo = document.createElement('video'); 7500 this.noSleepVideo.setAttribute('playsinline', ''); 7501 this.noSleepVideo.setAttribute('src', mediaFile); 7502 this.noSleepVideo.addEventListener('timeupdate', function (e) { 7503 if (this.noSleepVideo.currentTime > 0.5) { 7504 this.noSleepVideo.currentTime = Math.random(); 7505 } 7506 }.bind(this)); 7507 } 7508 } 7509 _createClass(NoSleep, [{ 7510 key: 'enable', 7511 value: function enable() { 7512 if (oldIOS) { 7513 this.disable(); 7514 this.noSleepTimer = window.setInterval(function () { 7515 window.location.href = '/'; 7516 window.setTimeout(window.stop, 0); 7517 }, 15000); 7518 } else { 7519 this.noSleepVideo.play(); 7520 } 7521 } 7522 }, { 7523 key: 'disable', 7524 value: function disable() { 7525 if (oldIOS) { 7526 if (this.noSleepTimer) { 7527 window.clearInterval(this.noSleepTimer); 7528 this.noSleepTimer = null; 7529 } 7530 } else { 7531 this.noSleepVideo.pause(); 7532 } 7533 } 7534 }]); 7535 return NoSleep; 7536 }(); 7537 module.exports = NoSleep; 7538 }), 7539 (function(module, exports, __webpack_require__) { 7540 module.exports = 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+U
7540Qn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA='; 7541 }) 7542 ]); 7543 }); 7544 }); 7545 var NoSleep$1 = unwrapExports$$1(NoSleep); 7546 var nextDisplayId = 1000; 7547 var defaultLeftBounds = [0, 0, 0.5, 1]; 7548 var defaultRightBounds = [0.5, 0, 0.5, 1]; 7549 var raf = window.requestAnimationFrame; 7550 var caf = window.cancelAnimationFrame; 7551 function VRFrameData() { 7552 this.leftProjectionMatrix = new Float32Array(16);
vendor: 23,756 bytes, lines 7553-8221
7553 this.leftViewMatrix = new Float32Array(16); 7554 this.rightProjectionMatrix = new Float32Array(16); 7555 this.rightViewMatrix = new Float32Array(16); 7556 this.pose = null; 7557 } 7558 function VRDisplayCapabilities(config) { 7559 Object.defineProperties(this, { 7560 hasPosition: { 7561 writable: false, enumerable: true, value: config.hasPosition 7562 }, 7563 hasExternalDisplay: { 7564 writable: false, enumerable: true, value: config.hasExternalDisplay 7565 }, 7566 canPresent: { 7567 writable: false, enumerable: true, value: config.canPresent 7568 }, 7569 maxLayers: { 7570 writable: false, enumerable: true, value: config.maxLayers 7571 }, 7572 hasOrientation: { 7573 enumerable: true, get: function get() { 7574 deprecateWarning('VRDisplayCapabilities.prototype.hasOrientation', 'VRDisplay.prototype.getFrameData'); 7575 return config.hasOrientation; 7576 } 7577 } 7578 }); 7579 } 7580 function VRDisplay(config) { 7581 config = config || {}; 7582 var USE_WAKELOCK = 'wakelock' in config ? config.wakelock : true; 7583 this.isPolyfilled = true; 7584 this.displayId = nextDisplayId++; 7585 this.displayName = ''; 7586 this.depthNear = 0.01; 7587 this.depthFar = 10000.0; 7588 this.isPresenting = false; 7589 Object.defineProperty(this, 'isConnected', { 7590 get: function get() { 7591 deprecateWarning('VRDisplay.prototype.isConnected', 'VRDisplayCapabilities.prototype.hasExternalDisplay'); 7592 return false; 7593 } 7594 }); 7595 this.capabilities = new VRDisplayCapabilities({ 7596 hasPosition: false, 7597 hasOrientation: false, 7598 hasExternalDisplay: false, 7599 canPresent: false, 7600 maxLayers: 1 7601 }); 7602 this.stageParameters = null; 7603 this.waitingForPresent_ = false; 7604 this.layer_ = null; 7605 this.originalParent_ = null; 7606 this.fullscreenElement_ = null; 7607 this.fullscreenWrapper_ = null; 7608 this.fullscreenElementCachedStyle_ = null; 7609 this.fullscreenEventTarget_ = null; 7610 this.fullscreenChangeHandler_ = null; 7611 this.fullscreenErrorHandler_ = null; 7612 if (USE_WAKELOCK && isMobile()) { 7613 this.wakelock_ = new NoSleep$1(); 7614 } 7615 } 7616 VRDisplay.prototype.getFrameData = function (frameData) { 7617 return frameDataFromPose(frameData, this._getPose(), this); 7618 }; 7619 VRDisplay.prototype.getPose = function () { 7620 deprecateWarning('VRDisplay.prototype.getPose', 'VRDisplay.prototype.getFrameData'); 7621 return this._getPose(); 7622 }; 7623 VRDisplay.prototype.resetPose = function () { 7624 deprecateWarning('VRDisplay.prototype.resetPose'); 7625 return this._resetPose(); 7626 }; 7627 VRDisplay.prototype.getImmediatePose = function () { 7628 deprecateWarning('VRDisplay.prototype.getImmediatePose', 'VRDisplay.prototype.getFrameData'); 7629 return this._getPose(); 7630 }; 7631 VRDisplay.prototype.requestAnimationFrame = function (callback) { 7632 return raf(callback); 7633 }; 7634 VRDisplay.prototype.cancelAnimationFrame = function (id) { 7635 return caf(id); 7636 }; 7637 VRDisplay.prototype.wrapForFullscreen = function (element) { 7638 if (isIOS()) { 7639 return element; 7640 } 7641 if (!this.fullscreenWrapper_) { 7642 this.fullscreenWrapper_ = document.createElement('div'); 7643 var cssProperties = ['height: ' + Math.min(screen.height, screen.width) + 'px !important', 'top: 0 !important', 'left: 0 !important', 'right: 0 !important', 'border: 0', 'margin: 0', 'padding: 0', 'z-index: 999999 !important', 'position: fixed']; 7644 this.fullscreenWrapper_.setAttribute('style', cssProperties.join('; ') + ';'); 7645 this.fullscreenWrapper_.classList.add('webvr-polyfill-fullscreen-wrapper'); 7646 } 7647 if (this.fullscreenElement_ == element) { 7648 return this.fullscreenWrapper_; 7649 } 7650 if (this.fullscreenElement_) { 7651 if (this.originalParent_) { 7652 this.originalParent_.appendChild(this.fullscreenElement_); 7653 } else { 7654 this.fullscreenElement_.parentElement.removeChild(this.fullscreenElement_); 7655 } 7656 } 7657 this.fullscreenElement_ = element; 7658 this.originalParent_ = element.parentElement; 7659 if (!this.originalParent_) { 7660 document.body.appendChild(element); 7661 } 7662 if (!this.fullscreenWrapper_.parentElement) { 7663 var parent = this.fullscreenElement_.parentElement; 7664 parent.insertBefore(this.fullscreenWrapper_, this.fullscreenElement_); 7665 parent.removeChild(this.fullscreenElement_); 7666 } 7667 this.fullscreenWrapper_.insertBefore(this.fullscreenElement_, this.fullscreenWrapper_.firstChild); 7668 this.fullscreenElementCachedStyle_ = this.fullscreenElement_.getAttribute('style'); 7669 var self = this; 7670 function applyFullscreenElementStyle() { 7671 if (!self.fullscreenElement_) { 7672 return; 7673 } 7674 var cssProperties = ['position: absolute', 'top: 0', 'left: 0', 'width: ' + Math.max(screen.width, screen.height) + 'px', 'height: ' + Math.min(screen.height, screen.width) + 'px', 'border: 0', 'margin: 0', 'padding: 0']; 7675 self.fullscreenElement_.setAttribute('style', cssProperties.join('; ') + ';'); 7676 } 7677 applyFullscreenElementStyle(); 7678 return this.fullscreenWrapper_; 7679 }; 7680 VRDisplay.prototype.removeFullscreenWrapper = function () { 7681 if (!this.fullscreenElement_) { 7682 return; 7683 } 7684 var element = this.fullscreenElement_; 7685 if (this.fullscreenElementCachedStyle_) { 7686 element.setAttribute('style', this.fullscreenElementCachedStyle_); 7687 } else { 7688 element.removeAttribute('style'); 7689 } 7690 this.fullscreenElement_ = null; 7691 this.fullscreenElementCachedStyle_ = null; 7692 var parent = this.fullscreenWrapper_.parentElement; 7693 this.fullscreenWrapper_.removeChild(element); 7694 if (this.originalParent_ === parent) { 7695 parent.insertBefore(element, this.fullscreenWrapper_); 7696 } 7697 else if (this.originalParent_) { 7698 this.originalParent_.appendChild(element); 7699 } 7700 parent.removeChild(this.fullscreenWrapper_); 7701 return element; 7702 }; 7703 VRDisplay.prototype.requestPresent = function (layers) { 7704 var wasPresenting = this.isPresenting; 7705 var self = this; 7706 if (!(layers instanceof Array)) { 7707 deprecateWarning('VRDisplay.prototype.requestPresent with non-array argument', 'an array of VRLayers as the first argument'); 7708 layers = [layers]; 7709 } 7710 return new Promise(function (resolve, reject) { 7711 if (!self.capabilities.canPresent) { 7712 reject(new Error('VRDisplay is not capable of presenting.')); 7713 return; 7714 } 7715 if (layers.length == 0 || layers.length > self.capabilities.maxLayers) { 7716 reject(new Error('Invalid number of layers.')); 7717 return; 7718 } 7719 var incomingLayer = layers[0]; 7720 if (!incomingLayer.source) { 7721 resolve(); 7722 return; 7723 } 7724 var leftBounds = incomingLayer.leftBounds || defaultLeftBounds; 7725 var rightBounds = incomingLayer.rightBounds || defaultRightBounds; 7726 if (wasPresenting) { 7727 var layer = self.layer_; 7728 if (layer.source !== incomingLayer.source) { 7729 layer.source = incomingLayer.source; 7730 } 7731 for (var i = 0; i < 4; i++) { 7732 layer.leftBounds[i] = leftBounds[i]; 7733 layer.rightBounds[i] = rightBounds[i]; 7734 } 7735 self.wrapForFullscreen(self.layer_.source); 7736 self.updatePresent_(); 7737 resolve(); 7738 return; 7739 } 7740 self.layer_ = { 7741 predistorted: incomingLayer.predistorted, 7742 source: incomingLayer.source, 7743 leftBounds: leftBounds.slice(0), 7744 rightBounds: rightBounds.slice(0) 7745 }; 7746 self.waitingForPresent_ = false; 7747 if (self.layer_ && self.layer_.source) { 7748 var fullscreenElement = self.wrapForFullscreen(self.layer_.source); 7749 var onFullscreenChange = function onFullscreenChange() { 7750 var actualFullscreenElement = getFullscreenElement(); 7751 self.isPresenting = fullscreenElement === actualFullscreenElement; 7752 if (self.isPresenting) { 7753 if (screen.orientation && screen.orientation.lock) { 7754 screen.orientation.lock('landscape-primary').catch(function (error) { 7755 console.error('screen.orientation.lock() failed due to', error.message); 7756 }); 7757 } 7758 self.waitingForPresent_ = false; 7759 self.beginPresent_(); 7760 resolve(); 7761 } else { 7762 if (screen.orientation && screen.orientation.unlock) { 7763 screen.orientation.unlock(); 7764 } 7765 self.removeFullscreenWrapper(); 7766 self.disableWakeLock(); 7767 self.endPresent_(); 7768 self.removeFullscreenListeners_(); 7769 } 7770 self.fireVRDisplayPresentChange_(); 7771 }; 7772 var onFullscreenError = function onFullscreenError() { 7773 if (!self.waitingForPresent_) { 7774 return; 7775 } 7776 self.removeFullscreenWrapper(); 7777 self.removeFullscreenListeners_(); 7778 self.disableWakeLock(); 7779 self.waitingForPresent_ = false; 7780 self.isPresenting = false; 7781 reject(new Error('Unable to present.')); 7782 }; 7783 self.addFullscreenListeners_(fullscreenElement, onFullscreenChange, onFullscreenError); 7784 if (requestFullscreen(fullscreenElement)) { 7785 self.enableWakeLock(); 7786 self.waitingForPresent_ = true; 7787 } else if (isIOS() || isWebViewAndroid()) { 7788 self.enableWakeLock(); 7789 self.isPresenting = true; 7790 self.beginPresent_(); 7791 self.fireVRDisplayPresentChange_(); 7792 resolve(); 7793 } 7794 } 7795 if (!self.waitingForPresent_ && !isIOS()) { 7796 exitFullscreen(); 7797 reject(new Error('Unable to present.')); 7798 } 7799 }); 7800 }; 7801 VRDisplay.prototype.exitPresent = function () { 7802 var wasPresenting = this.isPresenting; 7803 var self = this; 7804 this.isPresenting = false; 7805 this.layer_ = null; 7806 this.disableWakeLock(); 7807 return new Promise(function (resolve, reject) { 7808 if (wasPresenting) { 7809 if (!exitFullscreen() && isIOS()) { 7810 self.endPresent_(); 7811 self.fireVRDisplayPresentChange_(); 7812 } 7813 if (isWebViewAndroid()) { 7814 self.removeFullscreenWrapper(); 7815 self.removeFullscreenListeners_(); 7816 self.endPresent_(); 7817 self.fireVRDisplayPresentChange_(); 7818 } 7819 resolve(); 7820 } else { 7821 reject(new Error('Was not presenting to VRDisplay.')); 7822 } 7823 }); 7824 }; 7825 VRDisplay.prototype.getLayers = function () { 7826 if (this.layer_) { 7827 return [this.layer_]; 7828 } 7829 return []; 7830 }; 7831 VRDisplay.prototype.fireVRDisplayPresentChange_ = function () { 7832 var event = new CustomEvent('vrdisplaypresentchange', { detail: { display: this } }); 7833 window.dispatchEvent(event); 7834 }; 7835 VRDisplay.prototype.fireVRDisplayConnect_ = function () { 7836 var event = new CustomEvent('vrdisplayconnect', { detail: { display: this } }); 7837 window.dispatchEvent(event); 7838 }; 7839 VRDisplay.prototype.addFullscreenListeners_ = function (element, changeHandler, errorHandler) { 7840 this.removeFullscreenListeners_(); 7841 this.fullscreenEventTarget_ = element; 7842 this.fullscreenChangeHandler_ = changeHandler; 7843 this.fullscreenErrorHandler_ = errorHandler; 7844 if (changeHandler) { 7845 if (document.fullscreenEnabled) { 7846 element.addEventListener('fullscreenchange', changeHandler, false); 7847 } else if (document.webkitFullscreenEnabled) { 7848 element.addEventListener('webkitfullscreenchange', changeHandler, false); 7849 } else if (document.mozFullScreenEnabled) { 7850 document.addEventListener('mozfullscreenchange', changeHandler, false); 7851 } else if (document.msFullscreenEnabled) { 7852 element.addEventListener('msfullscreenchange', changeHandler, false); 7853 } 7854 } 7855 if (errorHandler) { 7856 if (document.fullscreenEnabled) { 7857 element.addEventListener('fullscreenerror', errorHandler, false); 7858 } else if (document.webkitFullscreenEnabled) { 7859 element.addEventListener('webkitfullscreenerror', errorHandler, false); 7860 } else if (document.mozFullScreenEnabled) { 7861 document.addEventListener('mozfullscreenerror', errorHandler, false); 7862 } else if (document.msFullscreenEnabled) { 7863 element.addEventListener('msfullscreenerror', errorHandler, false); 7864 } 7865 } 7866 }; 7867 VRDisplay.prototype.removeFullscreenListeners_ = function () { 7868 if (!this.fullscreenEventTarget_) return; 7869 var element = this.fullscreenEventTarget_; 7870 if (this.fullscreenChangeHandler_) { 7871 var changeHandler = this.fullscreenChangeHandler_; 7872 element.removeEventListener('fullscreenchange', changeHandler, false); 7873 element.removeEventListener('webkitfullscreenchange', changeHandler, false); 7874 document.removeEventListener('mozfullscreenchange', changeHandler, false); 7875 element.removeEventListener('msfullscreenchange', changeHandler, false); 7876 } 7877 if (this.fullscreenErrorHandler_) { 7878 var errorHandler = this.fullscreenErrorHandler_; 7879 element.removeEventListener('fullscreenerror', errorHandler, false); 7880 element.removeEventListener('webkitfullscreenerror', errorHandler, false); 7881 document.removeEventListener('mozfullscreenerror', errorHandler, false); 7882 element.removeEventListener('msfullscreenerror', errorHandler, false); 7883 } 7884 this.fullscreenEventTarget_ = null; 7885 this.fullscreenChangeHandler_ = null; 7886 this.fullscreenErrorHandler_ = null; 7887 }; 7888 VRDisplay.prototype.enableWakeLock = function () { 7889 if (this.wakelock_) { 7890 this.wakelock_.enable(); 7891 } 7892 }; 7893 VRDisplay.prototype.disableWakeLock = function () { 7894 if (this.wakelock_) { 7895 this.wakelock_.disable(); 7896 } 7897 }; 7898 VRDisplay.prototype.beginPresent_ = function () { 7899 }; 7900 VRDisplay.prototype.endPresent_ = function () { 7901 }; 7902 VRDisplay.prototype.submitFrame = function (pose) { 7903 }; 7904 VRDisplay.prototype.getEyeParameters = function (whichEye) { 7905 return null; 7906 }; 7907 var config = { 7908 ADDITIONAL_VIEWERS: [], 7909 DEFAULT_VIEWER: '', 7910 MOBILE_WAKE_LOCK: true, 7911 DEBUG: false, 7912 DPDB_URL: 'https://dpdb.webvr.rocks/dpdb.json', 7913 K_FILTER: 0.98, 7914 PREDICTION_TIME_S: 0.040, 7915 CARDBOARD_UI_DISABLED: false, 7916 ROTATE_INSTRUCTIONS_DISABLED: false, 7917 YAW_ONLY: false, 7918 BUFFER_SCALE: 0.5, 7919 DIRTY_SUBMIT_FRAME_BINDINGS: false 7920 }; 7921 var Eye = { 7922 LEFT: 'left', 7923 RIGHT: 'right' 7924 }; 7925 function CardboardVRDisplay(config$$1) { 7926 var defaults = extend({}, config); 7927 config$$1 = extend(defaults, config$$1 || {}); 7928 VRDisplay.call(this, { 7929 wakelock: config$$1.MOBILE_WAKE_LOCK 7930 }); 7931 this.config = config$$1; 7932 this.displayName = 'Cardboard VRDisplay'; 7933 this.capabilities = new VRDisplayCapabilities({ 7934 hasPosition: false, 7935 hasOrientation: true, 7936 hasExternalDisplay: false, 7937 canPresent: true, 7938 maxLayers: 1 7939 }); 7940 this.stageParameters = null; 7941 this.bufferScale_ = this.config.BUFFER_SCALE; 7942 this.poseSensor_ = new PoseSensor(this.config); 7943 this.distorter_ = null; 7944 this.cardboardUI_ = null; 7945 this.dpdb_ = new Dpdb(this.config.DPDB_URL, this.onDeviceParamsUpdated_.bind(this)); 7946 this.deviceInfo_ = new DeviceInfo(this.dpdb_.getDeviceParams(), config$$1.ADDITIONAL_VIEWERS); 7947 this.viewerSelector_ = new ViewerSelector(config$$1.DEFAULT_VIEWER); 7948 this.viewerSelector_.onChange(this.onViewerChanged_.bind(this)); 7949 this.deviceInfo_.setViewer(this.viewerSelector_.getCurrentViewer()); 7950 if (!this.config.ROTATE_INSTRUCTIONS_DISABLED) { 7951 this.rotateInstructions_ = new RotateInstructions(); 7952 } 7953 if (isIOS()) { 7954 window.addEventListener('resize', this.onResize_.bind(this)); 7955 } 7956 } 7957 CardboardVRDisplay.prototype = Object.create(VRDisplay.prototype); 7958 CardboardVRDisplay.prototype._getPose = function () { 7959 return { 7960 position: null, 7961 orientation: this.poseSensor_.getOrientation(), 7962 linearVelocity: null, 7963 linearAcceleration: null, 7964 angularVelocity: null, 7965 angularAcceleration: null 7966 }; 7967 }; 7968 CardboardVRDisplay.prototype._resetPose = function () { 7969 if (this.poseSensor_.resetPose) { 7970 this.poseSensor_.resetPose(); 7971 } 7972 }; 7973 CardboardVRDisplay.prototype._getFieldOfView = function (whichEye) { 7974 var fieldOfView; 7975 if (whichEye == Eye.LEFT) { 7976 fieldOfView = this.deviceInfo_.getFieldOfViewLeftEye(); 7977 } else if (whichEye == Eye.RIGHT) { 7978 fieldOfView = this.deviceInfo_.getFieldOfViewRightEye(); 7979 } else { 7980 console.error('Invalid eye provided: %s', whichEye); 7981 return null; 7982 } 7983 return fieldOfView; 7984 }; 7985 CardboardVRDisplay.prototype._getEyeOffset = function (whichEye) { 7986 var offset; 7987 if (whichEye == Eye.LEFT) { 7988 offset = [-this.deviceInfo_.viewer.interLensDistance * 0.5, 0.0, 0.0]; 7989 } else if (whichEye == Eye.RIGHT) { 7990 offset = [this.deviceInfo_.viewer.interLensDistance * 0.5, 0.0, 0.0]; 7991 } else { 7992 console.error('Invalid eye provided: %s', whichEye); 7993 return null; 7994 } 7995 return offset; 7996 }; 7997 CardboardVRDisplay.prototype.getEyeParameters = function (whichEye) { 7998 var offset = this._getEyeOffset(whichEye); 7999 var fieldOfView = this._getFieldOfView(whichEye); 8000 var eyeParams = { 8001 offset: offset, 8002 renderWidth: this.deviceInfo_.device.width * 0.5 * this.bufferScale_, 8003 renderHeight: this.deviceInfo_.device.height * this.bufferScale_ 8004 }; 8005 Object.defineProperty(eyeParams, 'fieldOfView', { 8006 enumerable: true, 8007 get: function get() { 8008 deprecateWarning('VRFieldOfView', 'VRFrameData\'s projection matrices'); 8009 return fieldOfView; 8010 } 8011 }); 8012 return eyeParams; 8013 }; 8014 CardboardVRDisplay.prototype.onDeviceParamsUpdated_ = function (newParams) { 8015 if (this.config.DEBUG) { 8016 console.log('DPDB reported that device params were updated.'); 8017 } 8018 this.deviceInfo_.updateDeviceParams(newParams); 8019 if (this.distorter_) { 8020 this.distorter_.updateDeviceInfo(this.deviceInfo_); 8021 } 8022 }; 8023 CardboardVRDisplay.prototype.updateBounds_ = function () { 8024 if (this.layer_ && this.distorter_ && (this.layer_.leftBounds || this.layer_.rightBounds)) { 8025 this.distorter_.setTextureBounds(this.layer_.leftBounds, this.layer_.rightBounds); 8026 } 8027 }; 8028 CardboardVRDisplay.prototype.beginPresent_ = function () { 8029 var gl = this.layer_.source.getContext('webgl'); 8030 if (!gl) gl = this.layer_.source.getContext('experimental-webgl'); 8031 if (!gl) gl = this.layer_.source.getContext('webgl2'); 8032 if (!gl) return; 8033 if (this.layer_.predistorted) { 8034 if (!this.config.CARDBOARD_UI_DISABLED) { 8035 gl.canvas.width = getScreenWidth() * this.bufferScale_; 8036 gl.canvas.height = getScreenHeight() * this.bufferScale_; 8037 this.cardboardUI_ = new CardboardUI(gl); 8038 } 8039 } else { 8040 if (!this.config.CARDBOARD_UI_DISABLED) { 8041 this.cardboardUI_ = new CardboardUI(gl); 8042 } 8043 this.distorter_ = new CardboardDistorter(gl, this.cardboardUI_, this.config.BUFFER_SCALE, this.config.DIRTY_SUBMIT_FRAME_BINDINGS); 8044 this.distorter_.updateDeviceInfo(this.deviceInfo_); 8045 } 8046 if (this.cardboardUI_) { 8047 this.cardboardUI_.listen(function (e) { 8048 this.viewerSelector_.show(this.layer_.source.parentElement); 8049 e.stopPropagation(); 8050 e.preventDefault(); 8051 }.bind(this), function (e) { 8052 this.exitPresent(); 8053 e.stopPropagation(); 8054 e.preventDefault(); 8055 }.bind(this)); 8056 } 8057 if (this.rotateInstructions_) { 8058 if (isLandscapeMode() && isMobile()) { 8059 this.rotateInstructions_.showTemporarily(3000, this.layer_.source.parentElement); 8060 } else { 8061 this.rotateInstructions_.update(); 8062 } 8063 } 8064 this.orientationHandler = this.onOrientationChange_.bind(this); 8065 window.addEventListener('orientationchange', this.orientationHandler); 8066 this.vrdisplaypresentchangeHandler = this.updateBounds_.bind(this); 8067 window.addEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler); 8068 this.fireVRDisplayDeviceParamsChange_(); 8069 }; 8070 CardboardVRDisplay.prototype.endPresent_ = function () { 8071 if (this.distorter_) { 8072 this.distorter_.destroy(); 8073 this.distorter_ = null; 8074 } 8075 if (this.cardboardUI_) { 8076 this.cardboardUI_.destroy(); 8077 this.cardboardUI_ = null; 8078 } 8079 if (this.rotateInstructions_) { 8080 this.rotateInstructions_.hide(); 8081 } 8082 this.viewerSelector_.hide(); 8083 window.removeEventListener('orientationchange', this.orientationHandler); 8084 window.removeEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler); 8085 }; 8086 CardboardVRDisplay.prototype.updatePresent_ = function () { 8087 this.endPresent_(); 8088 this.beginPresent_(); 8089 }; 8090 CardboardVRDisplay.prototype.submitFrame = function (pose) { 8091 if (this.distorter_) { 8092 this.updateBounds_(); 8093 this.distorter_.submitFrame(); 8094 } else if (this.cardboardUI_ && this.layer_) { 8095 var canvas = this.layer_.source.getContext('webgl').canvas; 8096 if (canvas.width != this.lastWidth || canvas.height != this.lastHeight) { 8097 this.cardboardUI_.onResize(); 8098 } 8099 this.lastWidth = canvas.width; 8100 this.lastHeight = canvas.height; 8101 this.cardboardUI_.render(); 8102 } 8103 }; 8104 CardboardVRDisplay.prototype.onOrientationChange_ = function (e) { 8105 this.viewerSelector_.hide(); 8106 if (this.rotateInstructions_) { 8107 this.rotateInstructions_.update(); 8108 } 8109 this.onResize_(); 8110 }; 8111 CardboardVRDisplay.prototype.onResize_ = function (e) { 8112 if (this.layer_) { 8113 var gl = this.layer_.source.getContext('webgl'); 8114 var cssProperties = ['position: absolute', 'top: 0', 'left: 0', 8115 'width: 100vw', 'height: 100vh', 'border: 0', 'margin: 0', 8116 'padding: 0px', 'box-sizing: content-box']; 8117 gl.canvas.setAttribute('style', cssProperties.join('; ') + ';'); 8118 safariCssSizeWorkaround(gl.canvas); 8119 } 8120 }; 8121 CardboardVRDisplay.prototype.onViewerChanged_ = function (viewer) { 8122 this.deviceInfo_.setViewer(viewer); 8123 if (this.distorter_) { 8124 this.distorter_.updateDeviceInfo(this.deviceInfo_); 8125 } 8126 this.fireVRDisplayDeviceParamsChange_(); 8127 }; 8128 CardboardVRDisplay.prototype.fireVRDisplayDeviceParamsChange_ = function () { 8129 var event = new CustomEvent('vrdisplaydeviceparamschange', { 8130 detail: { 8131 vrdisplay: this, 8132 deviceInfo: this.deviceInfo_ 8133 } 8134 }); 8135 window.dispatchEvent(event); 8136 }; 8137 CardboardVRDisplay.VRFrameData = VRFrameData; 8138 CardboardVRDisplay.VRDisplay = VRDisplay; 8139 return CardboardVRDisplay; 8140 }))); 8141 }); 8142 var CardboardVRDisplay = unwrapExports(cardboardVrDisplay); 8143 8144 var version = "0.10.6"; 8145 8146 var DefaultConfig = { 8147 ADDITIONAL_VIEWERS: [], 8148 DEFAULT_VIEWER: '', 8149 PROVIDE_MOBILE_VRDISPLAY: true, 8150 GET_VR_DISPLAYS_TIMEOUT: 1000, 8151 MOBILE_WAKE_LOCK: true, 8152 DEBUG: false, 8153 DPDB_URL: 'https://dpdb.webvr.rocks/dpdb.json', 8154 K_FILTER: 0.98, 8155 PREDICTION_TIME_S: 0.040, 8156 TOUCH_PANNER_DISABLED: true, 8157 CARDBOARD_UI_DISABLED: false, 8158 ROTATE_INSTRUCTIONS_DISABLED: false, 8159 YAW_ONLY: false, 8160 BUFFER_SCALE: 0.5, 8161 DIRTY_SUBMIT_FRAME_BINDINGS: false 8162 }; 8163 8164 function WebVRPolyfill(config) { 8165 this.config = extend(extend({}, DefaultConfig), config); 8166 this.polyfillDisplays = []; 8167 this.enabled = false; 8168 this.hasNative = 'getVRDisplays' in navigator; 8169 this.native = {}; 8170 this.native.getVRDisplays = navigator.getVRDisplays; 8171 this.native.VRFrameData = window.VRFrameData; 8172 this.native.VRDisplay = window.VRDisplay; 8173 if (!this.hasNative || this.config.PROVIDE_MOBILE_VRDISPLAY && isMobile()) { 8174 this.enable(); 8175 this.getVRDisplays().then(function (displays) { 8176 if (displays && displays[0] && displays[0].fireVRDisplayConnect_) { 8177 displays[0].fireVRDisplayConnect_(); 8178 } 8179 }); 8180 } 8181 } 8182 WebVRPolyfill.prototype.getPolyfillDisplays = function () { 8183 if (this._polyfillDisplaysPopulated) { 8184 return this.polyfillDisplays; 8185 } 8186 if (isMobile()) { 8187 var vrDisplay = new CardboardVRDisplay({ 8188 ADDITIONAL_VIEWERS: this.config.ADDITIONAL_VIEWERS, 8189 DEFAULT_VIEWER: this.config.DEFAULT_VIEWER, 8190 MOBILE_WAKE_LOCK: this.config.MOBILE_WAKE_LOCK, 8191 DEBUG: this.config.DEBUG, 8192 DPDB_URL: this.config.DPDB_URL, 8193 CARDBOARD_UI_DISABLED: this.config.CARDBOARD_UI_DISABLED, 8194 K_FILTER: this.config.K_FILTER, 8195 PREDICTION_TIME_S: this.config.PREDICTION_TIME_S, 8196 TOUCH_PANNER_DISABLED: this.config.TOUCH_PANNER_DISABLED, 8197 ROTATE_INSTRUCTIONS_DISABLED: this.config.ROTATE_INSTRUCTIONS_DISABLED, 8198 YAW_ONLY: this.config.YAW_ONLY, 8199 BUFFER_SCALE: this.config.BUFFER_SCALE, 8200 DIRTY_SUBMIT_FRAME_BINDINGS: this.config.DIRTY_SUBMIT_FRAME_BINDINGS 8201 }); 8202 this.polyfillDisplays.push(vrDisplay); 8203 } 8204 this._polyfillDisplaysPopulated = true; 8205 return this.polyfillDisplays; 8206 }; 8207 WebVRPolyfill.prototype.enable = function () { 8208 this.enabled = true; 8209 if (this.hasNative && this.native.VRFrameData) { 8210 var NativeVRFrameData = this.native.VRFrameData; 8211 var nativeFrameData = new this.native.VRFrameData(); 8212 var nativeGetFrameData = this.native.VRDisplay.prototype.getFrameData; 8213 window.VRDisplay.prototype.getFrameData = function (frameData) { 8214 if (frameData instanceof NativeVRFrameData) { 8215 nativeGetFrameData.call(this, frameData); 8216 return; 8217 } 8218 nativeGetFrameData.call(this, nativeFrameData); 8219 frameData.pose = nativeFrameData.pose; 8220 copyArray(nativeFrameData.leftProjectionMatrix, frameData.leftProjectionMatrix); 8221 copyArray(nativeFrameData.rightProjectionMatrix, frameData.rightProjectionMatrix);
8222 copyArray(nativeFrameData.leftViewMatrix, frameData.leftViewMatrix); 8223 copyArray(nativeFrameData.rightViewMatrix, frameData.rightViewMatrix); 8224 }; 8225 } 8226 navigator.getVRDisplays = this.getVRDisplays.bind(this); 8227 window.VRDisplay = CardboardVRDisplay.VRDisplay; 8228 window.VRFrameData = CardboardVRDisplay.VRFrameData; 8229 }; 8230 WebVRPolyfill.prototype.getVRDisplays = function () { 8231 var _this = this; 8232 var config = this.config; 8233 if (!this.hasNative) { 8234 return Promise.resolve(this.getPolyfillDisplays()); 8235 } 8236 var timeoutId; 8237 var vrDisplaysNative = this.native.getVRDisplays.call(navigator); 8238 var timeoutPromise = new Promise(function (resolve) { 8239 timeoutId = setTimeout(function () { 8240 console.warn('Native WebVR implementation detected, but `getVRDisplays()` failed to resolve. Falling back to polyfill.'); 8241 resolve([]); 8242 }, config.GET_VR_DISPLAYS_TIMEOUT); 8243 }); 8244 return race([vrDisplaysNative, timeoutPromise]).then(function (nativeDisplays) { 8245 clearTimeout(timeoutId); 8246 return nativeDisplays.length > 0 ? nativeDisplays : _this.getPolyfillDisplays(); 8247 }); 8248 }; 8249 WebVRPolyfill.version = version; 8250 WebVRPolyfill.VRFrameData = CardboardVRDisplay.VRFrameData; 8251 WebVRPolyfill.VRDisplay = CardboardVRDisplay.VRDisplay; 8252 8253 8254 var webvrPolyfill = Object.freeze({ 8255 default: WebVRPolyfill 8256 }); 8257 8258 var require$$0 = ( webvrPolyfill && WebVRPolyfill ) || webvrPolyfill; 8259 8260 if (typeof commonjsGlobal$1 !== 'undefined' && commonjsGlobal$1.window) { 8261 if (!commonjsGlobal$1.document) { 8262 commonjsGlobal$1.document = commonjsGlobal$1.window.document; 8263 } 8264 if (!commonjsGlobal$1.navigator) { 8265 commonjsGlobal$1.navigator = commonjsGlobal$1.window.navigator; 8266 } 8267 } 8268 var src = require$$0; 8269 8270 return src; 8271 8272 }))); 8273 }); 8274 8275 var WebVRPolyfill = unwrapExports(webvrPolyfill); 8276 8277 // Polyfills 8278 8279 if ( Number.EPSILON === undefined ) { 8280 8281 Number.EPSILON = Math.pow( 2, - 52 ); 8282 8283 } 8284 8285 if ( Number.isInteger === undefined ) { 8286 8287 // Missing in IE 8288 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger 8289 8290 Number.isInteger = function ( value ) { 8291 8292 return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value; 8293 8294 }; 8295 8296 } 8297 8298 // 8299 8300 if ( Math.sign === undefined ) { 8301 8302 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign 8303 8304 Math.sign = function ( x ) { 8305 8306 return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x; 8307 8308 }; 8309 8310 } 8311 8312 if ( 'name' in Function.prototype === false ) { 8313 8314 // Missing in IE 8315 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name 8316 8317 Object.defineProperty( Function.prototype, 'name', { 8318 8319 get: function () { 8320 8321 return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ]; 8322 8323 } 8324 8325 } ); 8326 8327 } 8328 8329 if ( Object.assign === undefined ) { 8330 8331 // Missing in IE 8332 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 8333 8334 ( function () { 8335 8336 Object.assign = function ( target ) { 8337 8338 if ( target === undefined || target === null ) { 8339 8340 throw new TypeError( 'Cannot convert undefined or null to object' ); 8341 8342 } 8343 8344 var output = Object( target ); 8345 8346 for ( var index = 1; index < arguments.length; index ++ ) { 8347 8348 var source = arguments[ index ]; 8349 8350 if ( source !== undefined && source !== null ) { 8351 8352 for ( var nextKey in source ) { 8353 8354 if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { 8355 8356 output[ nextKey ] = source[ nextKey ]; 8357 8358 } 8359 8360 } 8361 8362 } 8363 8364 } 8365 8366 return output; 8367 8368 }; 8369 8370 } )(); 8371 8372 } 8373 8374 /** 8375 * https://github.com/mrdoob/eventdispatcher.js/ 8376 */ 8377 8378 function EventDispatcher() {} 8379 8380 Object.assign( EventDispatcher.prototype, { 8381
vendor: 22,083 bytes, lines 8382-9520
8382 addEventListener: function ( type, listener ) { 8383 8384 if ( this._listeners === undefined ) this._listeners = {}; 8385 8386 var listeners = this._listeners; 8387 8388 if ( listeners[ type ] === undefined ) { 8389 8390 listeners[ type ] = []; 8391 8392 } 8393 8394 if ( listeners[ type ].indexOf( listener ) === - 1 ) { 8395 8396 listeners[ type ].push( listener ); 8397 8398 } 8399 8400 }, 8401 8402 hasEventListener: function ( type, listener ) { 8403 8404 if ( this._listeners === undefined ) return false; 8405 8406 var listeners = this._listeners; 8407 8408 return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; 8409 8410 }, 8411 8412 removeEventListener: function ( type, listener ) { 8413 8414 if ( this._listeners === undefined ) return; 8415 8416 var listeners = this._listeners; 8417 var listenerArray = listeners[ type ]; 8418 8419 if ( listenerArray !== undefined ) { 8420 8421 var index = listenerArray.indexOf( listener ); 8422 8423 if ( index !== - 1 ) { 8424 8425 listenerArray.splice( index, 1 ); 8426 8427 } 8428 8429 } 8430 8431 }, 8432 8433 dispatchEvent: function ( event ) { 8434 8435 if ( this._listeners === undefined ) return; 8436 8437 var listeners = this._listeners; 8438 var listenerArray = listeners[ event.type ]; 8439 8440 if ( listenerArray !== undefined ) { 8441 8442 event.target = this; 8443 8444 var array = listenerArray.slice( 0 ); 8445 8446 for ( var i = 0, l = array.length; i < l; i ++ ) { 8447 8448 array[ i ].call( this, event ); 8449 8450 } 8451 8452 } 8453 8454 } 8455 8456 } ); 8457 8458 var REVISION = '93'; 8459 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; 8460 var CullFaceNone = 0; 8461 var CullFaceBack = 1; 8462 var CullFaceFront = 2; 8463 var PCFShadowMap = 1; 8464 var PCFSoftShadowMap = 2; 8465 var FrontSide = 0; 8466 var BackSide = 1; 8467 var DoubleSide = 2; 8468 var FlatShading = 1; 8469 var NoColors = 0; 8470 var FaceColors = 1; 8471 var VertexColors = 2; 8472 var NoBlending = 0; 8473 var NormalBlending = 1; 8474 var AdditiveBlending = 2; 8475 var SubtractiveBlending = 3; 8476 var MultiplyBlending = 4; 8477 var CustomBlending = 5; 8478 var AddEquation = 100; 8479 var SubtractEquation = 101; 8480 var ReverseSubtractEquation = 102; 8481 var MinEquation = 103; 8482 var MaxEquation = 104; 8483 var ZeroFactor = 200; 8484 var OneFactor = 201; 8485 var SrcColorFactor = 202; 8486 var OneMinusSrcColorFactor = 203; 8487 var SrcAlphaFactor = 204; 8488 var OneMinusSrcAlphaFactor = 205; 8489 var DstAlphaFactor = 206; 8490 var OneMinusDstAlphaFactor = 207; 8491 var DstColorFactor = 208; 8492 var OneMinusDstColorFactor = 209; 8493 var SrcAlphaSaturateFactor = 210; 8494 var NeverDepth = 0; 8495 var AlwaysDepth = 1; 8496 var LessDepth = 2; 8497 var LessEqualDepth = 3; 8498 var EqualDepth = 4; 8499 var GreaterEqualDepth = 5; 8500 var GreaterDepth = 6; 8501 var NotEqualDepth = 7; 8502 var MultiplyOperation = 0; 8503 var MixOperation = 1; 8504 var AddOperation = 2; 8505 var NoToneMapping = 0; 8506 var LinearToneMapping = 1; 8507 var ReinhardToneMapping = 2; 8508 var Uncharted2ToneMapping = 3; 8509 var CineonToneMapping = 4; 8510 var UVMapping = 300; 8511 var CubeReflectionMapping = 301; 8512 var CubeRefractionMapping = 302; 8513 var EquirectangularReflectionMapping = 303; 8514 var EquirectangularRefractionMapping = 304; 8515 var SphericalReflectionMapping = 305; 8516 var CubeUVReflectionMapping = 306; 8517 var CubeUVRefractionMapping = 307; 8518 var RepeatWrapping = 1000; 8519 var ClampToEdgeWrapping = 1001; 8520 var MirroredRepeatWrapping = 1002; 8521 var NearestFilter = 1003; 8522 var NearestMipMapNearestFilter = 1004; 8523 var NearestMipMapLinearFilter = 1005; 8524 var LinearFilter = 1006; 8525 var LinearMipMapNearestFilter = 1007; 8526 var LinearMipMapLinearFilter = 1008; 8527 var UnsignedByteType = 1009; 8528 var ByteType = 1010; 8529 var ShortType = 1011; 8530 var UnsignedShortType = 1012; 8531 var IntType = 1013; 8532 var UnsignedIntType = 1014; 8533 var FloatType = 1015; 8534 var HalfFloatType = 1016; 8535 var UnsignedShort4444Type = 1017; 8536 var UnsignedShort5551Type = 1018; 8537 var UnsignedShort565Type = 1019; 8538 var UnsignedInt248Type = 1020; 8539 var AlphaFormat = 1021; 8540 var RGBFormat = 1022; 8541 var RGBAFormat = 1023; 8542 var LuminanceFormat = 1024; 8543 var LuminanceAlphaFormat = 1025; 8544 var DepthFormat = 1026; 8545 var DepthStencilFormat = 1027; 8546 var RGB_S3TC_DXT1_Format = 33776; 8547 var RGBA_S3TC_DXT1_Format = 33777; 8548 var RGBA_S3TC_DXT3_Format = 33778; 8549 var RGBA_S3TC_DXT5_Format = 33779; 8550 var RGB_PVRTC_4BPPV1_Format = 35840; 8551 var RGB_PVRTC_2BPPV1_Format = 35841; 8552 var RGBA_PVRTC_4BPPV1_Format = 35842; 8553 var RGBA_PVRTC_2BPPV1_Format = 35843; 8554 var RGB_ETC1_Format = 36196; 8555 var RGBA_ASTC_4x4_Format = 37808; 8556 var RGBA_ASTC_5x4_Format = 37809; 8557 var RGBA_ASTC_5x5_Format = 37810; 8558 var RGBA_ASTC_6x5_Format = 37811; 8559 var RGBA_ASTC_6x6_Format = 37812; 8560 var RGBA_ASTC_8x5_Format = 37813; 8561 var RGBA_ASTC_8x6_Format = 37814; 8562 var RGBA_ASTC_8x8_Format = 37815; 8563 var RGBA_ASTC_10x5_Format = 37816; 8564 var RGBA_ASTC_10x6_Format = 37817; 8565 var RGBA_ASTC_10x8_Format = 37818; 8566 var RGBA_ASTC_10x10_Format = 37819; 8567 var RGBA_ASTC_12x10_Format = 37820; 8568 var RGBA_ASTC_12x12_Format = 37821; 8569 var LoopOnce = 2200; 8570 var LoopRepeat = 2201; 8571 var LoopPingPong = 2202; 8572 var InterpolateDiscrete = 2300; 8573 var InterpolateLinear = 2301; 8574 var InterpolateSmooth = 2302; 8575 var ZeroCurvatureEnding = 2400; 8576 var ZeroSlopeEnding = 2401; 8577 var WrapAroundEnding = 2402; 8578 var TrianglesDrawMode = 0; 8579 var TriangleStripDrawMode = 1; 8580 var TriangleFanDrawMode = 2; 8581 var LinearEncoding = 3000; 8582 var sRGBEncoding = 3001; 8583 var GammaEncoding = 3007; 8584 var RGBEEncoding = 3002; 8585 var RGBM7Encoding = 3004; 8586 var RGBM16Encoding = 3005; 8587 var RGBDEncoding = 3006; 8588 var BasicDepthPacking = 3200; 8589 var RGBADepthPacking = 3201; 8590 8591 /** 8592 * @author alteredq / http://alteredqualia.com/ 8593 * @author mrdoob / http://mrdoob.com/ 8594 */ 8595 8596 var _Math = { 8597 8598 DEG2RAD: Math.PI / 180, 8599 RAD2DEG: 180 / Math.PI, 8600 8601 generateUUID: ( function () { 8602 8603 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 8604 8605 var lut = []; 8606 8607 for ( var i = 0; i < 256; i ++ ) { 8608 8609 lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); 8610 8611 } 8612 8613 return function generateUUID() { 8614 8615 var d0 = Math.random() * 0xffffffff | 0; 8616 var d1 = Math.random() * 0xffffffff | 0; 8617 var d2 = Math.random() * 0xffffffff | 0; 8618 var d3 = Math.random() * 0xffffffff | 0; 8619 var uuid = lut[ d0 & 0xff ] + lut[ d0 >> 8 & 0xff ] + lut[ d0 >> 16 & 0xff ] + lut[ d0 >> 24 & 0xff ] + '-' + 8620 lut[ d1 & 0xff ] + lut[ d1 >> 8 & 0xff ] + '-' + lut[ d1 >> 16 & 0x0f | 0x40 ] + lut[ d1 >> 24 & 0xff ] + '-' + 8621 lut[ d2 & 0x3f | 0x80 ] + lut[ d2 >> 8 & 0xff ] + '-' + lut[ d2 >> 16 & 0xff ] + lut[ d2 >> 24 & 0xff ] + 8622 lut[ d3 & 0xff ] + lut[ d3 >> 8 & 0xff ] + lut[ d3 >> 16 & 0xff ] + lut[ d3 >> 24 & 0xff ]; 8623 8624 // .toUpperCase() here flattens concatenated strings to save heap memory space. 8625 return uuid.toUpperCase(); 8626 8627 }; 8628 8629 } )(), 8630 8631 clamp: function ( value, min, max ) { 8632 8633 return Math.max( min, Math.min( max, value ) ); 8634 8635 }, 8636 8637 // compute euclidian modulo of m % n 8638 // https://en.wikipedia.org/wiki/Modulo_operation 8639 8640 euclideanModulo: function ( n, m ) { 8641 8642 return ( ( n % m ) + m ) % m; 8643 8644 }, 8645 8646 // Linear mapping from range <a1, a2> to range <b1, b2> 8647 8648 mapLinear: function ( x, a1, a2, b1, b2 ) { 8649 8650 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); 8651 8652 }, 8653 8654 // https://en.wikipedia.org/wiki/Linear_interpolation 8655 8656 lerp: function ( x, y, t ) { 8657 8658 return ( 1 - t ) * x + t * y; 8659 8660 }, 8661 8662 // http://en.wikipedia.org/wiki/Smoothstep 8663 8664 smoothstep: function ( x, min, max ) { 8665 8666 if ( x <= min ) return 0; 8667 if ( x >= max ) return 1; 8668 8669 x = ( x - min ) / ( max - min ); 8670 8671 return x * x * ( 3 - 2 * x ); 8672 8673 }, 8674 8675 smootherstep: function ( x, min, max ) { 8676 8677 if ( x <= min ) return 0; 8678 if ( x >= max ) return 1; 8679 8680 x = ( x - min ) / ( max - min ); 8681 8682 return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); 8683 8684 }, 8685 8686 // Random integer from <low, high> interval 8687 8688 randInt: function ( low, high ) { 8689 8690 return low + Math.floor( Math.random() * ( high - low + 1 ) ); 8691 8692 }, 8693 8694 // Random float from <low, high> interval 8695 8696 randFloat: function ( low, high ) { 8697 8698 return low + Math.random() * ( high - low ); 8699 8700 }, 8701 8702 // Random float from <-range/2, range/2> interval 8703 8704 randFloatSpread: function ( range ) { 8705 8706 return range * ( 0.5 - Math.random() ); 8707 8708 }, 8709 8710 degToRad: function ( degrees ) { 8711 8712 return degrees * _Math.DEG2RAD; 8713 8714 }, 8715 8716 radToDeg: function ( radians ) { 8717 8718 return radians * _Math.RAD2DEG; 8719 8720 }, 8721 8722 isPowerOfTwo: function ( value ) { 8723 8724 return ( value & ( value - 1 ) ) === 0 && value !== 0; 8725 8726 }, 8727 8728 ceilPowerOfTwo: function ( value ) { 8729 8730 return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); 8731 8732 }, 8733 8734 floorPowerOfTwo: function ( value ) { 8735 8736 return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); 8737 8738 } 8739 8740 }; 8741 8742 /** 8743 * @author mrdoob / http://mrdoob.com/ 8744 * @author philogb / http://blog.thejit.org/ 8745 * @author egraether / http://egraether.com/ 8746 * @author zz85 / http://www.lab4games.net/zz85/blog 8747 */ 8748 8749 function Vector2( x, y ) { 8750 8751 this.x = x || 0; 8752 this.y = y || 0; 8753 8754 } 8755 8756 Object.defineProperties( Vector2.prototype, { 8757 8758 "width": { 8759 8760 get: function () { 8761 8762 return this.x; 8763 8764 }, 8765 8766 set: function ( value ) { 8767 8768 this.x = value; 8769 8770 } 8771 8772 }, 8773 8774 "height": { 8775 8776 get: function () { 8777 8778 return this.y; 8779 8780 }, 8781 8782 set: function ( value ) { 8783 8784 this.y = value; 8785 8786 } 8787 8788 } 8789 8790 } ); 8791 8792 Object.assign( Vector2.prototype, { 8793 8794 isVector2: true, 8795 8796 set: function ( x, y ) { 8797 8798 this.x = x; 8799 this.y = y; 8800 8801 return this; 8802 8803 }, 8804 8805 setScalar: function ( scalar ) { 8806 8807 this.x = scalar; 8808 this.y = scalar; 8809 8810 return this; 8811 8812 }, 8813 8814 setX: function ( x ) { 8815 8816 this.x = x; 8817 8818 return this; 8819 8820 }, 8821 8822 setY: function ( y ) { 8823 8824 this.y = y; 8825 8826 return this; 8827 8828 }, 8829 8830 setComponent: function ( index, value ) { 8831 8832 switch ( index ) { 8833 8834 case 0: this.x = value; break; 8835 case 1: this.y = value; break; 8836 default: throw new Error( 'index is out of range: ' + index ); 8837 8838 } 8839 8840 return this; 8841 8842 }, 8843 8844 getComponent: function ( index ) { 8845 8846 switch ( index ) { 8847 8848 case 0: return this.x; 8849 case 1: return this.y; 8850 default: throw new Error( 'index is out of range: ' + index ); 8851 8852 } 8853 8854 }, 8855 8856 clone: function () { 8857 8858 return new this.constructor( this.x, this.y ); 8859 8860 }, 8861 8862 copy: function ( v ) { 8863 8864 this.x = v.x; 8865 this.y = v.y; 8866 8867 return this; 8868 8869 }, 8870 8871 add: function ( v, w ) { 8872 8873 if ( w !== undefined ) { 8874 8875 console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 8876 return this.addVectors( v, w ); 8877 8878 } 8879 8880 this.x += v.x; 8881 this.y += v.y; 8882 8883 return this; 8884 8885 }, 8886 8887 addScalar: function ( s ) { 8888 8889 this.x += s; 8890 this.y += s; 8891 8892 return this; 8893 8894 }, 8895 8896 addVectors: function ( a, b ) { 8897 8898 this.x = a.x + b.x; 8899 this.y = a.y + b.y; 8900 8901 return this; 8902 8903 }, 8904 8905 addScaledVector: function ( v, s ) { 8906 8907 this.x += v.x * s; 8908 this.y += v.y * s; 8909 8910 return this; 8911 8912 }, 8913 8914 sub: function ( v, w ) { 8915 8916 if ( w !== undefined ) { 8917 8918 console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 8919 return this.subVectors( v, w ); 8920 8921 } 8922 8923 this.x -= v.x; 8924 this.y -= v.y; 8925 8926 return this; 8927 8928 }, 8929 8930 subScalar: function ( s ) { 8931 8932 this.x -= s; 8933 this.y -= s; 8934 8935 return this; 8936 8937 }, 8938 8939 subVectors: function ( a, b ) { 8940 8941 this.x = a.x - b.x; 8942 this.y = a.y - b.y; 8943 8944 return this; 8945 8946 }, 8947 8948 multiply: function ( v ) { 8949 8950 this.x *= v.x; 8951 this.y *= v.y; 8952 8953 return this; 8954 8955 }, 8956 8957 multiplyScalar: function ( scalar ) { 8958 8959 this.x *= scalar; 8960 this.y *= scalar; 8961 8962 return this; 8963 8964 }, 8965 8966 divide: function ( v ) { 8967 8968 this.x /= v.x; 8969 this.y /= v.y; 8970 8971 return this; 8972 8973 }, 8974 8975 divideScalar: function ( scalar ) { 8976 8977 return this.multiplyScalar( 1 / scalar ); 8978 8979 }, 8980 8981 applyMatrix3: function ( m ) { 8982 8983 var x = this.x, y = this.y; 8984 var e = m.elements; 8985 8986 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; 8987 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; 8988 8989 return this; 8990 8991 }, 8992 8993 min: function ( v ) { 8994 8995 this.x = Math.min( this.x, v.x ); 8996 this.y = Math.min( this.y, v.y ); 8997 8998 return this; 8999 9000 }, 9001 9002 max: function ( v ) { 9003 9004 this.x = Math.max( this.x, v.x ); 9005 this.y = Math.max( this.y, v.y ); 9006 9007 return this; 9008 9009 }, 9010 9011 clamp: function ( min, max ) { 9012 9013 // assumes min < max, componentwise 9014 9015 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 9016 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 9017 9018 return this; 9019 9020 }, 9021 9022 clampScalar: function () { 9023 9024 var min = new Vector2(); 9025 var max = new Vector2(); 9026 9027 return function clampScalar( minVal, maxVal ) { 9028 9029 min.set( minVal, minVal ); 9030 max.set( maxVal, maxVal ); 9031 9032 return this.clamp( min, max ); 9033 9034 }; 9035 9036 }(), 9037 9038 clampLength: function ( min, max ) { 9039 9040 var length = this.length(); 9041 9042 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 9043 9044 }, 9045 9046 floor: function () { 9047 9048 this.x = Math.floor( this.x ); 9049 this.y = Math.floor( this.y ); 9050 9051 return this; 9052 9053 }, 9054 9055 ceil: function () { 9056 9057 this.x = Math.ceil( this.x ); 9058 this.y = Math.ceil( this.y ); 9059 9060 return this; 9061 9062 }, 9063 9064 round: function () { 9065 9066 this.x = Math.round( this.x ); 9067 this.y = Math.round( this.y ); 9068 9069 return this; 9070 9071 }, 9072 9073 roundToZero: function () { 9074 9075 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 9076 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 9077 9078 return this; 9079 9080 }, 9081 9082 negate: function () { 9083 9084 this.x = - this.x; 9085 this.y = - this.y; 9086 9087 return this; 9088 9089 }, 9090 9091 dot: function ( v ) { 9092 9093 return this.x * v.x + this.y * v.y; 9094 9095 }, 9096 9097 lengthSq: function () { 9098 9099 return this.x * this.x + this.y * this.y; 9100 9101 }, 9102 9103 length: function () { 9104 9105 return Math.sqrt( this.x * this.x + this.y * this.y ); 9106 9107 }, 9108 9109 manhattanLength: function () { 9110 9111 return Math.abs( this.x ) + Math.abs( this.y ); 9112 9113 }, 9114 9115 normalize: function () { 9116 9117 return this.divideScalar( this.length() || 1 ); 9118 9119 }, 9120 9121 angle: function () { 9122 9123 // computes the angle in radians with respect to the positive x-axis 9124 9125 var angle = Math.atan2( this.y, this.x ); 9126 9127 if ( angle < 0 ) angle += 2 * Math.PI; 9128 9129 return angle; 9130 9131 }, 9132 9133 distanceTo: function ( v ) { 9134 9135 return Math.sqrt( this.distanceToSquared( v ) ); 9136 9137 }, 9138 9139 distanceToSquared: function ( v ) { 9140 9141 var dx = this.x - v.x, dy = this.y - v.y; 9142 return dx * dx + dy * dy; 9143 9144 }, 9145 9146 manhattanDistanceTo: function ( v ) { 9147 9148 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); 9149 9150 }, 9151 9152 setLength: function ( length ) { 9153 9154 return this.normalize().multiplyScalar( length ); 9155 9156 }, 9157 9158 lerp: function ( v, alpha ) { 9159 9160 this.x += ( v.x - this.x ) * alpha; 9161 this.y += ( v.y - this.y ) * alpha; 9162 9163 return this; 9164 9165 }, 9166 9167 lerpVectors: function ( v1, v2, alpha ) { 9168 9169 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 9170 9171 }, 9172 9173 equals: function ( v ) { 9174 9175 return ( ( v.x === this.x ) && ( v.y === this.y ) ); 9176 9177 }, 9178 9179 fromArray: function ( array, offset ) { 9180 9181 if ( offset === undefined ) offset = 0; 9182 9183 this.x = array[ offset ]; 9184 this.y = array[ offset + 1 ]; 9185 9186 return this; 9187 9188 }, 9189 9190 toArray: function ( array, offset ) { 9191 9192 if ( array === undefined ) array = []; 9193 if ( offset === undefined ) offset = 0; 9194 9195 array[ offset ] = this.x; 9196 array[ offset + 1 ] = this.y; 9197 9198 return array; 9199 9200 }, 9201 9202 fromBufferAttribute: function ( attribute, index, offset ) { 9203 9204 if ( offset !== undefined ) { 9205 9206 console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); 9207 9208 } 9209 9210 this.x = attribute.getX( index ); 9211 this.y = attribute.getY( index ); 9212 9213 return this; 9214 9215 }, 9216 9217 rotateAround: function ( center, angle ) { 9218 9219 var c = Math.cos( angle ), s = Math.sin( angle ); 9220 9221 var x = this.x - center.x; 9222 var y = this.y - center.y; 9223 9224 this.x = x * c - y * s + center.x; 9225 this.y = x * s + y * c + center.y; 9226 9227 return this; 9228 9229 } 9230 9231 } ); 9232 9233 /** 9234 * @author mrdoob / http://mrdoob.com/ 9235 * @author supereggbert / http://www.paulbrunt.co.uk/ 9236 * @author philogb / http://blog.thejit.org/ 9237 * @author jordi_ros / http://plattsoft.com 9238 * @author D1plo1d / http://github.com/D1plo1d 9239 * @author alteredq / http://alteredqualia.com/ 9240 * @author mikael emtinger / http://gomo.se/ 9241 * @author timknip / http://www.floorplanner.com/ 9242 * @author bhouston / http://clara.io 9243 * @author WestLangley / http://github.com/WestLangley 9244 */ 9245 9246 function Matrix4() { 9247 9248 this.elements = [ 9249 9250 1, 0, 0, 0, 9251 0, 1, 0, 0, 9252 0, 0, 1, 0, 9253 0, 0, 0, 1 9254 9255 ]; 9256 9257 if ( arguments.length > 0 ) { 9258 9259 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); 9260 9261 } 9262 9263 } 9264 9265 Object.assign( Matrix4.prototype, { 9266 9267 isMatrix4: true, 9268 9269 set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { 9270 9271 var te = this.elements; 9272 9273 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; 9274 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; 9275 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; 9276 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; 9277 9278 return this; 9279 9280 }, 9281 9282 identity: function () { 9283 9284 this.set( 9285 9286 1, 0, 0, 0, 9287 0, 1, 0, 0, 9288 0, 0, 1, 0, 9289 0, 0, 0, 1 9290 9291 ); 9292 9293 return this; 9294 9295 }, 9296 9297 clone: function () { 9298 9299 return new Matrix4().fromArray( this.elements ); 9300 9301 }, 9302 9303 copy: function ( m ) { 9304 9305 var te = this.elements; 9306 var me = m.elements; 9307 9308 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; 9309 te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; 9310 te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; 9311 te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; 9312 9313 return this; 9314 9315 }, 9316 9317 copyPosition: function ( m ) { 9318 9319 var te = this.elements, me = m.elements; 9320 9321 te[ 12 ] = me[ 12 ]; 9322 te[ 13 ] = me[ 13 ]; 9323 te[ 14 ] = me[ 14 ]; 9324 9325 return this; 9326 9327 }, 9328 9329 extractBasis: function ( xAxis, yAxis, zAxis ) { 9330 9331 xAxis.setFromMatrixColumn( this, 0 ); 9332 yAxis.setFromMatrixColumn( this, 1 ); 9333 zAxis.setFromMatrixColumn( this, 2 ); 9334 9335 return this; 9336 9337 }, 9338 9339 makeBasis: function ( xAxis, yAxis, zAxis ) { 9340 9341 this.set( 9342 xAxis.x, yAxis.x, zAxis.x, 0, 9343 xAxis.y, yAxis.y, zAxis.y, 0, 9344 xAxis.z, yAxis.z, zAxis.z, 0, 9345 0, 0, 0, 1 9346 ); 9347 9348 return this; 9349 9350 }, 9351 9352 extractRotation: function () { 9353 9354 var v1 = new Vector3(); 9355 9356 return function extractRotation( m ) { 9357 9358 // this method does not support reflection matrices 9359 9360 var te = this.elements; 9361 var me = m.elements; 9362 9363 var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); 9364 var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); 9365 var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); 9366 9367 te[ 0 ] = me[ 0 ] * scaleX; 9368 te[ 1 ] = me[ 1 ] * scaleX; 9369 te[ 2 ] = me[ 2 ] * scaleX; 9370 te[ 3 ] = 0; 9371 9372 te[ 4 ] = me[ 4 ] * scaleY; 9373 te[ 5 ] = me[ 5 ] * scaleY; 9374 te[ 6 ] = me[ 6 ] * scaleY; 9375 te[ 7 ] = 0; 9376 9377 te[ 8 ] = me[ 8 ] * scaleZ; 9378 te[ 9 ] = me[ 9 ] * scaleZ; 9379 te[ 10 ] = me[ 10 ] * scaleZ; 9380 te[ 11 ] = 0; 9381 9382 te[ 12 ] = 0; 9383 te[ 13 ] = 0; 9384 te[ 14 ] = 0; 9385 te[ 15 ] = 1; 9386 9387 return this; 9388 9389 }; 9390 9391 }(), 9392 9393 makeRotationFromEuler: function ( euler ) { 9394 9395 if ( ! ( euler && euler.isEuler ) ) { 9396 9397 console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); 9398 9399 } 9400 9401 var te = this.elements; 9402 9403 var x = euler.x, y = euler.y, z = euler.z; 9404 var a = Math.cos( x ), b = Math.sin( x ); 9405 var c = Math.cos( y ), d = Math.sin( y ); 9406 var e = Math.cos( z ), f = Math.sin( z ); 9407 9408 if ( euler.order === 'XYZ' ) { 9409 9410 var ae = a * e, af = a * f, be = b * e, bf = b * f; 9411 9412 te[ 0 ] = c * e; 9413 te[ 4 ] = - c * f; 9414 te[ 8 ] = d; 9415 9416 te[ 1 ] = af + be * d; 9417 te[ 5 ] = ae - bf * d; 9418 te[ 9 ] = - b * c; 9419 9420 te[ 2 ] = bf - ae * d; 9421 te[ 6 ] = be + af * d; 9422 te[ 10 ] = a * c; 9423 9424 } else if ( euler.order === 'YXZ' ) { 9425 9426 var ce = c * e, cf = c * f, de = d * e, df = d * f; 9427 9428 te[ 0 ] = ce + df * b; 9429 te[ 4 ] = de * b - cf; 9430 te[ 8 ] = a * d; 9431 9432 te[ 1 ] = a * f; 9433 te[ 5 ] = a * e; 9434 te[ 9 ] = - b; 9435 9436 te[ 2 ] = cf * b - de; 9437 te[ 6 ] = df + ce * b; 9438 te[ 10 ] = a * c; 9439 9440 } else if ( euler.order === 'ZXY' ) { 9441 9442 var ce = c * e, cf = c * f, de = d * e, df = d * f; 9443 9444 te[ 0 ] = ce - df * b; 9445 te[ 4 ] = - a * f; 9446 te[ 8 ] = de + cf * b; 9447 9448 te[ 1 ] = cf + de * b; 9449 te[ 5 ] = a * e; 9450 te[ 9 ] = df - ce * b; 9451 9452 te[ 2 ] = - a * d; 9453 te[ 6 ] = b; 9454 te[ 10 ] = a * c; 9455 9456 } else if ( euler.order === 'ZYX' ) { 9457 9458 var ae = a * e, af = a * f, be = b * e, bf = b * f; 9459 9460 te[ 0 ] = c * e; 9461 te[ 4 ] = be * d - af; 9462 te[ 8 ] = ae * d + bf; 9463 9464 te[ 1 ] = c * f; 9465 te[ 5 ] = bf * d + ae; 9466 te[ 9 ] = af * d - be; 9467 9468 te[ 2 ] = - d; 9469 te[ 6 ] = b * c; 9470 te[ 10 ] = a * c; 9471 9472 } else if ( euler.order === 'YZX' ) { 9473 9474 var ac = a * c, ad = a * d, bc = b * c, bd = b * d; 9475 9476 te[ 0 ] = c * e; 9477 te[ 4 ] = bd - ac * f; 9478 te[ 8 ] = bc * f + ad; 9479 9480 te[ 1 ] = f; 9481 te[ 5 ] = a * e; 9482 te[ 9 ] = - b * e; 9483 9484 te[ 2 ] = - d * e; 9485 te[ 6 ] = ad * f + bc; 9486 te[ 10 ] = ac - bd * f; 9487 9488 } else if ( euler.order === 'XZY' ) { 9489 9490 var ac = a * c, ad = a * d, bc = b * c, bd = b * d; 9491 9492 te[ 0 ] = c * e; 9493 te[ 4 ] = - f; 9494 te[ 8 ] = d * e; 9495 9496 te[ 1 ] = ac * f + bd; 9497 te[ 5 ] = a * e; 9498 te[ 9 ] = ad * f - bc; 9499 9500 te[ 2 ] = bc * f - ad; 9501 te[ 6 ] = b * e; 9502 te[ 10 ] = bd * f + ac; 9503 9504 } 9505 9506 // bottom row 9507 te[ 3 ] = 0; 9508 te[ 7 ] = 0; 9509 te[ 11 ] = 0; 9510 9511 // last column 9512 te[ 12 ] = 0; 9513 te[ 13 ] = 0; 9514 te[ 14 ] = 0; 9515 te[ 15 ] = 1; 9516 9517 return this; 9518 9519 }, 9520
9521 makeRotationFromQuaternion: function () { 9522 9523 var zero = new Vector3( 0, 0, 0 ); 9524 var one = new Vector3( 1, 1, 1 ); 9525 9526 return function makeRotationFromQuaternion( q ) { 9527 9528 return this.compose( zero, q, one ); 9529 9530 }; 9531 9532 }(), 9533 9534 lookAt: function () { 9535 9536 var x = new Vector3(); 9537 var y = new Vector3(); 9538 var z = new Vector3(); 9539 9540 return function lookAt( eye, target, up ) { 9541 9542 var te = this.elements; 9543 9544 z.subVectors( eye, target ); 9545 9546 if ( z.lengthSq() === 0 ) { 9547 9548 // eye and target are in the same position 9549 9550 z.z = 1; 9551 9552 } 9553 9554 z.normalize(); 9555 x.crossVectors( up, z ); 9556 9557 if ( x.lengthSq() === 0 ) { 9558 9559 // up and z are parallel 9560 9561 if ( Math.abs( up.z ) === 1 ) { 9562 9563 z.x += 0.0001; 9564 9565 } else { 9566 9567 z.z += 0.0001; 9568 9569 } 9570 9571 z.normalize(); 9572 x.crossVectors( up, z ); 9573 9574 } 9575 9576 x.normalize(); 9577 y.crossVectors( z, x ); 9578 9579 te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; 9580 te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; 9581 te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; 9582 9583 return this; 9584 9585 }; 9586 9587 }(), 9588 9589 multiply: function ( m, n ) { 9590 9591 if ( n !== undefined ) { 9592 9593 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); 9594 return this.multiplyMatrices( m, n ); 9595 9596 } 9597 9598 return this.multiplyMatrices( this, m ); 9599 9600 }, 9601 9602 premultiply: function ( m ) { 9603 9604 return this.multiplyMatrices( m, this ); 9605 9606 }, 9607 9608 multiplyMatrices: function ( a, b ) { 9609 9610 var ae = a.elements; 9611 var be = b.elements; 9612 var te = this.elements; 9613 9614 var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; 9615 var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; 9616 var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; 9617 var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; 9618 9619 var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; 9620 var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; 9621 var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; 9622 var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; 9623 9624 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; 9625 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; 9626 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; 9627 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; 9628 9629 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; 9630 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; 9631 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; 9632 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; 9633 9634 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; 9635 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; 9636 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; 9637 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; 9638 9639 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; 9640 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; 9641 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; 9642 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; 9643 9644 return this; 9645 9646 }, 9647 9648 multiplyScalar: function ( s ) { 9649 9650 var te = this.elements; 9651 9652 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; 9653 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; 9654 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; 9655 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; 9656 9657 return this; 9658 9659 }, 9660 9661 applyToBufferAttribute: function () { 9662 9663 var v1 = new Vector3(); 9664 9665 return function applyToBufferAttribute( attribute ) { 9666 9667 for ( var i = 0, l = attribute.count; i < l; i ++ ) { 9668 9669 v1.x = attribute.getX( i ); 9670 v1.y = attribute.getY( i ); 9671 v1.z = attribute.getZ( i ); 9672 9673 v1.applyMatrix4( this ); 9674 9675 attribute.setXYZ( i, v1.x, v1.y, v1.z ); 9676 9677 } 9678 9679 return attribute; 9680 9681 }; 9682 9683 }(), 9684 9685 determinant: function () { 9686 9687 var te = this.elements; 9688 9689 var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; 9690 var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; 9691 var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; 9692 var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; 9693 9694 //TODO: make this more efficient 9695 //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) 9696 9697 return ( 9698 n41 * ( 9699 + n14 * n23 * n32 9700 - n13 * n24 * n32 9701 - n14 * n22 * n33 9702 + n12 * n24 * n33 9703 + n13 * n22 * n34 9704 - n12 * n23 * n34 9705 ) + 9706 n42 * ( 9707 + n11 * n23 * n34 9708 - n11 * n24 * n33 9709 + n14 * n21 * n33 9710 - n13 * n21 * n34 9711 + n13 * n24 * n31 9712 - n14 * n23 * n31 9713 ) + 9714 n43 * ( 9715 + n11 * n24 * n32 9716 - n11 * n22 * n34 9717 - n14 * n21 * n32 9718 + n12 * n21 * n34 9719 + n14 * n22 * n31 9720 - n12 * n24 * n31 9721 ) + 9722 n44 * ( 9723 - n13 * n22 * n31 9724 - n11 * n23 * n32 9725 + n11 * n22 * n33 9726 + n13 * n21 * n32 9727 - n12 * n21 * n33 9728 + n12 * n23 * n31 9729 ) 9730 9731 ); 9732 9733 }, 9734
vendor: 31,485 bytes, lines 9735-11274
9735 transpose: function () { 9736 9737 var te = this.elements; 9738 var tmp; 9739 9740 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; 9741 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; 9742 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; 9743 9744 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; 9745 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; 9746 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; 9747 9748 return this; 9749 9750 }, 9751 9752 setPosition: function ( v ) { 9753 9754 var te = this.elements; 9755 9756 te[ 12 ] = v.x; 9757 te[ 13 ] = v.y; 9758 te[ 14 ] = v.z; 9759 9760 return this; 9761 9762 }, 9763 9764 getInverse: function ( m, throwOnDegenerate ) { 9765 9766 // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm 9767 var te = this.elements, 9768 me = m.elements, 9769 9770 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], 9771 n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], 9772 n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], 9773 n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], 9774 9775 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, 9776 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, 9777 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, 9778 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; 9779 9780 var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; 9781 9782 if ( det === 0 ) { 9783 9784 var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"; 9785 9786 if ( throwOnDegenerate === true ) { 9787 9788 throw new Error( msg ); 9789 9790 } else { 9791 9792 console.warn( msg ); 9793 9794 } 9795 9796 return this.identity(); 9797 9798 } 9799 9800 var detInv = 1 / det; 9801 9802 te[ 0 ] = t11 * detInv; 9803 te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; 9804 te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; 9805 te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; 9806 9807 te[ 4 ] = t12 * detInv; 9808 te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; 9809 te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; 9810 te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; 9811 9812 te[ 8 ] = t13 * detInv; 9813 te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; 9814 te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; 9815 te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; 9816 9817 te[ 12 ] = t14 * detInv; 9818 te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; 9819 te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; 9820 te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; 9821 9822 return this; 9823 9824 }, 9825 9826 scale: function ( v ) { 9827 9828 var te = this.elements; 9829 var x = v.x, y = v.y, z = v.z; 9830 9831 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; 9832 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; 9833 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; 9834 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; 9835 9836 return this; 9837 9838 }, 9839 9840 getMaxScaleOnAxis: function () { 9841 9842 var te = this.elements; 9843 9844 var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; 9845 var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; 9846 var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; 9847 9848 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); 9849 9850 }, 9851 9852 makeTranslation: function ( x, y, z ) { 9853 9854 this.set( 9855 9856 1, 0, 0, x, 9857 0, 1, 0, y, 9858 0, 0, 1, z, 9859 0, 0, 0, 1 9860 9861 ); 9862 9863 return this; 9864 9865 }, 9866 9867 makeRotationX: function ( theta ) { 9868 9869 var c = Math.cos( theta ), s = Math.sin( theta ); 9870 9871 this.set( 9872 9873 1, 0, 0, 0, 9874 0, c, - s, 0, 9875 0, s, c, 0, 9876 0, 0, 0, 1 9877 9878 ); 9879 9880 return this; 9881 9882 }, 9883 9884 makeRotationY: function ( theta ) { 9885 9886 var c = Math.cos( theta ), s = Math.sin( theta ); 9887 9888 this.set( 9889 9890 c, 0, s, 0, 9891 0, 1, 0, 0, 9892 - s, 0, c, 0, 9893 0, 0, 0, 1 9894 9895 ); 9896 9897 return this; 9898 9899 }, 9900 9901 makeRotationZ: function ( theta ) { 9902 9903 var c = Math.cos( theta ), s = Math.sin( theta ); 9904 9905 this.set( 9906 9907 c, - s, 0, 0, 9908 s, c, 0, 0, 9909 0, 0, 1, 0, 9910 0, 0, 0, 1 9911 9912 ); 9913 9914 return this; 9915 9916 }, 9917 9918 makeRotationAxis: function ( axis, angle ) { 9919 9920 // Based on http://www.gamedev.net/reference/articles/article1199.asp 9921 9922 var c = Math.cos( angle ); 9923 var s = Math.sin( angle ); 9924 var t = 1 - c; 9925 var x = axis.x, y = axis.y, z = axis.z; 9926 var tx = t * x, ty = t * y; 9927 9928 this.set( 9929 9930 tx * x + c, tx * y - s * z, tx * z + s * y, 0, 9931 tx * y + s * z, ty * y + c, ty * z - s * x, 0, 9932 tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 9933 0, 0, 0, 1 9934 9935 ); 9936 9937 return this; 9938 9939 }, 9940 9941 makeScale: function ( x, y, z ) { 9942 9943 this.set( 9944 9945 x, 0, 0, 0, 9946 0, y, 0, 0, 9947 0, 0, z, 0, 9948 0, 0, 0, 1 9949 9950 ); 9951 9952 return this; 9953 9954 }, 9955 9956 makeShear: function ( x, y, z ) { 9957 9958 this.set( 9959 9960 1, y, z, 0, 9961 x, 1, z, 0, 9962 x, y, 1, 0, 9963 0, 0, 0, 1 9964 9965 ); 9966 9967 return this; 9968 9969 }, 9970 9971 compose: function ( position, quaternion, scale ) { 9972 9973 var te = this.elements; 9974 9975 var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; 9976 var x2 = x + x, y2 = y + y, z2 = z + z; 9977 var xx = x * x2, xy = x * y2, xz = x * z2; 9978 var yy = y * y2, yz = y * z2, zz = z * z2; 9979 var wx = w * x2, wy = w * y2, wz = w * z2; 9980 9981 var sx = scale.x, sy = scale.y, sz = scale.z; 9982 9983 te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; 9984 te[ 1 ] = ( xy + wz ) * sx; 9985 te[ 2 ] = ( xz - wy ) * sx; 9986 te[ 3 ] = 0; 9987 9988 te[ 4 ] = ( xy - wz ) * sy; 9989 te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; 9990 te[ 6 ] = ( yz + wx ) * sy; 9991 te[ 7 ] = 0; 9992 9993 te[ 8 ] = ( xz + wy ) * sz; 9994 te[ 9 ] = ( yz - wx ) * sz; 9995 te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; 9996 te[ 11 ] = 0; 9997 9998 te[ 12 ] = position.x; 9999 te[ 13 ] = position.y; 10000 te[ 14 ] = position.z; 10001 te[ 15 ] = 1; 10002 10003 return this; 10004 10005 }, 10006 10007 decompose: function () { 10008 10009 var vector = new Vector3(); 10010 var matrix = new Matrix4(); 10011 10012 return function decompose( position, quaternion, scale ) { 10013 10014 var te = this.elements; 10015 10016 var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); 10017 var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); 10018 var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); 10019 10020 // if determine is negative, we need to invert one scale 10021 var det = this.determinant(); 10022 if ( det < 0 ) sx = - sx; 10023 10024 position.x = te[ 12 ]; 10025 position.y = te[ 13 ]; 10026 position.z = te[ 14 ]; 10027 10028 // scale the rotation part 10029 matrix.copy( this ); 10030 10031 var invSX = 1 / sx; 10032 var invSY = 1 / sy; 10033 var invSZ = 1 / sz; 10034 10035 matrix.elements[ 0 ] *= invSX; 10036 matrix.elements[ 1 ] *= invSX; 10037 matrix.elements[ 2 ] *= invSX; 10038 10039 matrix.elements[ 4 ] *= invSY; 10040 matrix.elements[ 5 ] *= invSY; 10041 matrix.elements[ 6 ] *= invSY; 10042 10043 matrix.elements[ 8 ] *= invSZ; 10044 matrix.elements[ 9 ] *= invSZ; 10045 matrix.elements[ 10 ] *= invSZ; 10046 10047 quaternion.setFromRotationMatrix( matrix ); 10048 10049 scale.x = sx; 10050 scale.y = sy; 10051 scale.z = sz; 10052 10053 return this; 10054 10055 }; 10056 10057 }(), 10058 10059 makePerspective: function ( left, right, top, bottom, near, far ) { 10060 10061 if ( far === undefined ) { 10062 10063 console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); 10064 10065 } 10066 10067 var te = this.elements; 10068 var x = 2 * near / ( right - left ); 10069 var y = 2 * near / ( top - bottom ); 10070 10071 var a = ( right + left ) / ( right - left ); 10072 var b = ( top + bottom ) / ( top - bottom ); 10073 var c = - ( far + near ) / ( far - near ); 10074 var d = - 2 * far * near / ( far - near ); 10075 10076 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; 10077 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; 10078 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; 10079 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; 10080 10081 return this; 10082 10083 }, 10084 10085 makeOrthographic: function ( left, right, top, bottom, near, far ) { 10086 10087 var te = this.elements; 10088 var w = 1.0 / ( right - left ); 10089 var h = 1.0 / ( top - bottom ); 10090 var p = 1.0 / ( far - near ); 10091 10092 var x = ( right + left ) * w; 10093 var y = ( top + bottom ) * h; 10094 var z = ( far + near ) * p; 10095 10096 te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; 10097 te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; 10098 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; 10099 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; 10100 10101 return this; 10102 10103 }, 10104 10105 equals: function ( matrix ) { 10106 10107 var te = this.elements; 10108 var me = matrix.elements; 10109 10110 for ( var i = 0; i < 16; i ++ ) { 10111 10112 if ( te[ i ] !== me[ i ] ) return false; 10113 10114 } 10115 10116 return true; 10117 10118 }, 10119 10120 fromArray: function ( array, offset ) { 10121 10122 if ( offset === undefined ) offset = 0; 10123 10124 for ( var i = 0; i < 16; i ++ ) { 10125 10126 this.elements[ i ] = array[ i + offset ]; 10127 10128 } 10129 10130 return this; 10131 10132 }, 10133 10134 toArray: function ( array, offset ) { 10135 10136 if ( array === undefined ) array = []; 10137 if ( offset === undefined ) offset = 0; 10138 10139 var te = this.elements; 10140 10141 array[ offset ] = te[ 0 ]; 10142 array[ offset + 1 ] = te[ 1 ]; 10143 array[ offset + 2 ] = te[ 2 ]; 10144 array[ offset + 3 ] = te[ 3 ]; 10145 10146 array[ offset + 4 ] = te[ 4 ]; 10147 array[ offset + 5 ] = te[ 5 ]; 10148 array[ offset + 6 ] = te[ 6 ]; 10149 array[ offset + 7 ] = te[ 7 ]; 10150 10151 array[ offset + 8 ] = te[ 8 ]; 10152 array[ offset + 9 ] = te[ 9 ]; 10153 array[ offset + 10 ] = te[ 10 ]; 10154 array[ offset + 11 ] = te[ 11 ]; 10155 10156 array[ offset + 12 ] = te[ 12 ]; 10157 array[ offset + 13 ] = te[ 13 ]; 10158 array[ offset + 14 ] = te[ 14 ]; 10159 array[ offset + 15 ] = te[ 15 ]; 10160 10161 return array; 10162 10163 } 10164 10165 } ); 10166 10167 /** 10168 * @author mikael emtinger / http://gomo.se/ 10169 * @author alteredq / http://alteredqualia.com/ 10170 * @author WestLangley / http://github.com/WestLangley 10171 * @author bhouston / http://clara.io 10172 */ 10173 10174 function Quaternion( x, y, z, w ) { 10175 10176 this._x = x || 0; 10177 this._y = y || 0; 10178 this._z = z || 0; 10179 this._w = ( w !== undefined ) ? w : 1; 10180 10181 } 10182 10183 Object.assign( Quaternion, { 10184 10185 slerp: function ( qa, qb, qm, t ) { 10186 10187 return qm.copy( qa ).slerp( qb, t ); 10188 10189 }, 10190 10191 slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { 10192 10193 // fuzz-free, array-based Quaternion SLERP operation 10194 10195 var x0 = src0[ srcOffset0 + 0 ], 10196 y0 = src0[ srcOffset0 + 1 ], 10197 z0 = src0[ srcOffset0 + 2 ], 10198 w0 = src0[ srcOffset0 + 3 ], 10199 10200 x1 = src1[ srcOffset1 + 0 ], 10201 y1 = src1[ srcOffset1 + 1 ], 10202 z1 = src1[ srcOffset1 + 2 ], 10203 w1 = src1[ srcOffset1 + 3 ]; 10204 10205 if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { 10206 10207 var s = 1 - t, 10208 10209 cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, 10210 10211 dir = ( cos >= 0 ? 1 : - 1 ), 10212 sqrSin = 1 - cos * cos; 10213 10214 // Skip the Slerp for tiny steps to avoid numeric problems: 10215 if ( sqrSin > Number.EPSILON ) { 10216 10217 var sin = Math.sqrt( sqrSin ), 10218 len = Math.atan2( sin, cos * dir ); 10219 10220 s = Math.sin( s * len ) / sin; 10221 t = Math.sin( t * len ) / sin; 10222 10223 } 10224 10225 var tDir = t * dir; 10226 10227 x0 = x0 * s + x1 * tDir; 10228 y0 = y0 * s + y1 * tDir; 10229 z0 = z0 * s + z1 * tDir; 10230 w0 = w0 * s + w1 * tDir; 10231 10232 // Normalize in case we just did a lerp: 10233 if ( s === 1 - t ) { 10234 10235 var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); 10236 10237 x0 *= f; 10238 y0 *= f; 10239 z0 *= f; 10240 w0 *= f; 10241 10242 } 10243 10244 } 10245 10246 dst[ dstOffset ] = x0; 10247 dst[ dstOffset + 1 ] = y0; 10248 dst[ dstOffset + 2 ] = z0; 10249 dst[ dstOffset + 3 ] = w0; 10250 10251 } 10252 10253 } ); 10254 10255 Object.defineProperties( Quaternion.prototype, { 10256 10257 x: { 10258 10259 get: function () { 10260 10261 return this._x; 10262 10263 }, 10264 10265 set: function ( value ) { 10266 10267 this._x = value; 10268 this.onChangeCallback(); 10269 10270 } 10271 10272 }, 10273 10274 y: { 10275 10276 get: function () { 10277 10278 return this._y; 10279 10280 }, 10281 10282 set: function ( value ) { 10283 10284 this._y = value; 10285 this.onChangeCallback(); 10286 10287 } 10288 10289 }, 10290 10291 z: { 10292 10293 get: function () { 10294 10295 return this._z; 10296 10297 }, 10298 10299 set: function ( value ) { 10300 10301 this._z = value; 10302 this.onChangeCallback(); 10303 10304 } 10305 10306 }, 10307 10308 w: { 10309 10310 get: function () { 10311 10312 return this._w; 10313 10314 }, 10315 10316 set: function ( value ) { 10317 10318 this._w = value; 10319 this.onChangeCallback(); 10320 10321 } 10322 10323 } 10324 10325 } ); 10326 10327 Object.assign( Quaternion.prototype, { 10328 10329 set: function ( x, y, z, w ) { 10330 10331 this._x = x; 10332 this._y = y; 10333 this._z = z; 10334 this._w = w; 10335 10336 this.onChangeCallback(); 10337 10338 return this; 10339 10340 }, 10341 10342 clone: function () { 10343 10344 return new this.constructor( this._x, this._y, this._z, this._w ); 10345 10346 }, 10347 10348 copy: function ( quaternion ) { 10349 10350 this._x = quaternion.x; 10351 this._y = quaternion.y; 10352 this._z = quaternion.z; 10353 this._w = quaternion.w; 10354 10355 this.onChangeCallback(); 10356 10357 return this; 10358 10359 }, 10360 10361 setFromEuler: function ( euler, update ) { 10362 10363 if ( ! ( euler && euler.isEuler ) ) { 10364 10365 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); 10366 10367 } 10368 10369 var x = euler._x, y = euler._y, z = euler._z, order = euler.order; 10370 10371 // http://www.mathworks.com/matlabcentral/fileexchange/ 10372 // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ 10373 // content/SpinCalc.m 10374 10375 var cos = Math.cos; 10376 var sin = Math.sin; 10377 10378 var c1 = cos( x / 2 ); 10379 var c2 = cos( y / 2 ); 10380 var c3 = cos( z / 2 ); 10381 10382 var s1 = sin( x / 2 ); 10383 var s2 = sin( y / 2 ); 10384 var s3 = sin( z / 2 ); 10385 10386 if ( order === 'XYZ' ) { 10387 10388 this._x = s1 * c2 * c3 + c1 * s2 * s3; 10389 this._y = c1 * s2 * c3 - s1 * c2 * s3; 10390 this._z = c1 * c2 * s3 + s1 * s2 * c3; 10391 this._w = c1 * c2 * c3 - s1 * s2 * s3; 10392 10393 } else if ( order === 'YXZ' ) { 10394 10395 this._x = s1 * c2 * c3 + c1 * s2 * s3; 10396 this._y = c1 * s2 * c3 - s1 * c2 * s3; 10397 this._z = c1 * c2 * s3 - s1 * s2 * c3; 10398 this._w = c1 * c2 * c3 + s1 * s2 * s3; 10399 10400 } else if ( order === 'ZXY' ) { 10401 10402 this._x = s1 * c2 * c3 - c1 * s2 * s3; 10403 this._y = c1 * s2 * c3 + s1 * c2 * s3; 10404 this._z = c1 * c2 * s3 + s1 * s2 * c3; 10405 this._w = c1 * c2 * c3 - s1 * s2 * s3; 10406 10407 } else if ( order === 'ZYX' ) { 10408 10409 this._x = s1 * c2 * c3 - c1 * s2 * s3; 10410 this._y = c1 * s2 * c3 + s1 * c2 * s3; 10411 this._z = c1 * c2 * s3 - s1 * s2 * c3; 10412 this._w = c1 * c2 * c3 + s1 * s2 * s3; 10413 10414 } else if ( order === 'YZX' ) { 10415 10416 this._x = s1 * c2 * c3 + c1 * s2 * s3; 10417 this._y = c1 * s2 * c3 + s1 * c2 * s3; 10418 this._z = c1 * c2 * s3 - s1 * s2 * c3; 10419 this._w = c1 * c2 * c3 - s1 * s2 * s3; 10420 10421 } else if ( order === 'XZY' ) { 10422 10423 this._x = s1 * c2 * c3 - c1 * s2 * s3; 10424 this._y = c1 * s2 * c3 - s1 * c2 * s3; 10425 this._z = c1 * c2 * s3 + s1 * s2 * c3; 10426 this._w = c1 * c2 * c3 + s1 * s2 * s3; 10427 10428 } 10429 10430 if ( update !== false ) this.onChangeCallback(); 10431 10432 return this; 10433 10434 }, 10435 10436 setFromAxisAngle: function ( axis, angle ) { 10437 10438 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm 10439 10440 // assumes axis is normalized 10441 10442 var halfAngle = angle / 2, s = Math.sin( halfAngle ); 10443 10444 this._x = axis.x * s; 10445 this._y = axis.y * s; 10446 this._z = axis.z * s; 10447 this._w = Math.cos( halfAngle ); 10448 10449 this.onChangeCallback(); 10450 10451 return this; 10452 10453 }, 10454 10455 setFromRotationMatrix: function ( m ) { 10456 10457 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm 10458 10459 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 10460 10461 var te = m.elements, 10462 10463 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], 10464 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], 10465 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], 10466 10467 trace = m11 + m22 + m33, 10468 s; 10469 10470 if ( trace > 0 ) { 10471 10472 s = 0.5 / Math.sqrt( trace + 1.0 ); 10473 10474 this._w = 0.25 / s; 10475 this._x = ( m32 - m23 ) * s; 10476 this._y = ( m13 - m31 ) * s; 10477 this._z = ( m21 - m12 ) * s; 10478 10479 } else if ( m11 > m22 && m11 > m33 ) { 10480 10481 s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); 10482 10483 this._w = ( m32 - m23 ) / s; 10484 this._x = 0.25 * s; 10485 this._y = ( m12 + m21 ) / s; 10486 this._z = ( m13 + m31 ) / s; 10487 10488 } else if ( m22 > m33 ) { 10489 10490 s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); 10491 10492 this._w = ( m13 - m31 ) / s; 10493 this._x = ( m12 + m21 ) / s; 10494 this._y = 0.25 * s; 10495 this._z = ( m23 + m32 ) / s; 10496 10497 } else { 10498 10499 s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); 10500 10501 this._w = ( m21 - m12 ) / s; 10502 this._x = ( m13 + m31 ) / s; 10503 this._y = ( m23 + m32 ) / s; 10504 this._z = 0.25 * s; 10505 10506 } 10507 10508 this.onChangeCallback(); 10509 10510 return this; 10511 10512 }, 10513 10514 setFromUnitVectors: function () { 10515 10516 // assumes direction vectors vFrom and vTo are normalized 10517 10518 var v1 = new Vector3(); 10519 var r; 10520 10521 var EPS = 0.000001; 10522 10523 return function setFromUnitVectors( vFrom, vTo ) { 10524 10525 if ( v1 === undefined ) v1 = new Vector3(); 10526 10527 r = vFrom.dot( vTo ) + 1; 10528 10529 if ( r < EPS ) { 10530 10531 r = 0; 10532 10533 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { 10534 10535 v1.set( - vFrom.y, vFrom.x, 0 ); 10536 10537 } else { 10538 10539 v1.set( 0, - vFrom.z, vFrom.y ); 10540 10541 } 10542 10543 } else { 10544 10545 v1.crossVectors( vFrom, vTo ); 10546 10547 } 10548 10549 this._x = v1.x; 10550 this._y = v1.y; 10551 this._z = v1.z; 10552 this._w = r; 10553 10554 return this.normalize(); 10555 10556 }; 10557 10558 }(), 10559 10560 inverse: function () { 10561 10562 // quaternion is assumed to have unit length 10563 10564 return this.conjugate(); 10565 10566 }, 10567 10568 conjugate: function () { 10569 10570 this._x *= - 1; 10571 this._y *= - 1; 10572 this._z *= - 1; 10573 10574 this.onChangeCallback(); 10575 10576 return this; 10577 10578 }, 10579 10580 dot: function ( v ) { 10581 10582 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; 10583 10584 }, 10585 10586 lengthSq: function () { 10587 10588 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; 10589 10590 }, 10591 10592 length: function () { 10593 10594 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); 10595 10596 }, 10597 10598 normalize: function () { 10599 10600 var l = this.length(); 10601 10602 if ( l === 0 ) { 10603 10604 this._x = 0; 10605 this._y = 0; 10606 this._z = 0; 10607 this._w = 1; 10608 10609 } else { 10610 10611 l = 1 / l; 10612 10613 this._x = this._x * l; 10614 this._y = this._y * l; 10615 this._z = this._z * l; 10616 this._w = this._w * l; 10617 10618 } 10619 10620 this.onChangeCallback(); 10621 10622 return this; 10623 10624 }, 10625 10626 multiply: function ( q, p ) { 10627 10628 if ( p !== undefined ) { 10629 10630 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); 10631 return this.multiplyQuaternions( q, p ); 10632 10633 } 10634 10635 return this.multiplyQuaternions( this, q ); 10636 10637 }, 10638 10639 premultiply: function ( q ) { 10640 10641 return this.multiplyQuaternions( q, this ); 10642 10643 }, 10644 10645 multiplyQuaternions: function ( a, b ) { 10646 10647 // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm 10648 10649 var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; 10650 var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; 10651 10652 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; 10653 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; 10654 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; 10655 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; 10656 10657 this.onChangeCallback(); 10658 10659 return this; 10660 10661 }, 10662 10663 slerp: function ( qb, t ) { 10664 10665 if ( t === 0 ) return this; 10666 if ( t === 1 ) return this.copy( qb ); 10667 10668 var x = this._x, y = this._y, z = this._z, w = this._w; 10669 10670 // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ 10671 10672 var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; 10673 10674 if ( cosHalfTheta < 0 ) { 10675 10676 this._w = - qb._w; 10677 this._x = - qb._x; 10678 this._y = - qb._y; 10679 this._z = - qb._z; 10680 10681 cosHalfTheta = - cosHalfTheta; 10682 10683 } else { 10684 10685 this.copy( qb ); 10686 10687 } 10688 10689 if ( cosHalfTheta >= 1.0 ) { 10690 10691 this._w = w; 10692 this._x = x; 10693 this._y = y; 10694 this._z = z; 10695 10696 return this; 10697 10698 } 10699 10700 var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta ); 10701 10702 if ( Math.abs( sinHalfTheta ) < 0.001 ) { 10703 10704 this._w = 0.5 * ( w + this._w ); 10705 this._x = 0.5 * ( x + this._x ); 10706 this._y = 0.5 * ( y + this._y ); 10707 this._z = 0.5 * ( z + this._z ); 10708 10709 return this; 10710 10711 } 10712 10713 var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); 10714 var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, 10715 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; 10716 10717 this._w = ( w * ratioA + this._w * ratioB ); 10718 this._x = ( x * ratioA + this._x * ratioB ); 10719 this._y = ( y * ratioA + this._y * ratioB ); 10720 this._z = ( z * ratioA + this._z * ratioB ); 10721 10722 this.onChangeCallback(); 10723 10724 return this; 10725 10726 }, 10727 10728 equals: function ( quaternion ) { 10729 10730 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); 10731 10732 }, 10733 10734 fromArray: function ( array, offset ) { 10735 10736 if ( offset === undefined ) offset = 0; 10737 10738 this._x = array[ offset ]; 10739 this._y = array[ offset + 1 ]; 10740 this._z = array[ offset + 2 ]; 10741 this._w = array[ offset + 3 ]; 10742 10743 this.onChangeCallback(); 10744 10745 return this; 10746 10747 }, 10748 10749 toArray: function ( array, offset ) { 10750 10751 if ( array === undefined ) array = []; 10752 if ( offset === undefined ) offset = 0; 10753 10754 array[ offset ] = this._x; 10755 array[ offset + 1 ] = this._y; 10756 array[ offset + 2 ] = this._z; 10757 array[ offset + 3 ] = this._w; 10758 10759 return array; 10760 10761 }, 10762 10763 onChange: function ( callback ) { 10764 10765 this.onChangeCallback = callback; 10766 10767 return this; 10768 10769 }, 10770 10771 onChangeCallback: function () {} 10772 10773 } ); 10774 10775 /** 10776 * @author mrdoob / http://mrdoob.com/ 10777 * @author kile / http://kile.stravaganza.org/ 10778 * @author philogb / http://blog.thejit.org/ 10779 * @author mikael emtinger / http://gomo.se/ 10780 * @author egraether / http://egraether.com/ 10781 * @author WestLangley / http://github.com/WestLangley 10782 */ 10783 10784 function Vector3( x, y, z ) { 10785 10786 this.x = x || 0; 10787 this.y = y || 0; 10788 this.z = z || 0; 10789 10790 } 10791 10792 Object.assign( Vector3.prototype, { 10793 10794 isVector3: true, 10795 10796 set: function ( x, y, z ) { 10797 10798 this.x = x; 10799 this.y = y; 10800 this.z = z; 10801 10802 return this; 10803 10804 }, 10805 10806 setScalar: function ( scalar ) { 10807 10808 this.x = scalar; 10809 this.y = scalar; 10810 this.z = scalar; 10811 10812 return this; 10813 10814 }, 10815 10816 setX: function ( x ) { 10817 10818 this.x = x; 10819 10820 return this; 10821 10822 }, 10823 10824 setY: function ( y ) { 10825 10826 this.y = y; 10827 10828 return this; 10829 10830 }, 10831 10832 setZ: function ( z ) { 10833 10834 this.z = z; 10835 10836 return this; 10837 10838 }, 10839 10840 setComponent: function ( index, value ) { 10841 10842 switch ( index ) { 10843 10844 case 0: this.x = value; break; 10845 case 1: this.y = value; break; 10846 case 2: this.z = value; break; 10847 default: throw new Error( 'index is out of range: ' + index ); 10848 10849 } 10850 10851 return this; 10852 10853 }, 10854 10855 getComponent: function ( index ) { 10856 10857 switch ( index ) { 10858 10859 case 0: return this.x; 10860 case 1: return this.y; 10861 case 2: return this.z; 10862 default: throw new Error( 'index is out of range: ' + index ); 10863 10864 } 10865 10866 }, 10867 10868 clone: function () { 10869 10870 return new this.constructor( this.x, this.y, this.z ); 10871 10872 }, 10873 10874 copy: function ( v ) { 10875 10876 this.x = v.x; 10877 this.y = v.y; 10878 this.z = v.z; 10879 10880 return this; 10881 10882 }, 10883 10884 add: function ( v, w ) { 10885 10886 if ( w !== undefined ) { 10887 10888 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 10889 return this.addVectors( v, w ); 10890 10891 } 10892 10893 this.x += v.x; 10894 this.y += v.y; 10895 this.z += v.z; 10896 10897 return this; 10898 10899 }, 10900 10901 addScalar: function ( s ) { 10902 10903 this.x += s; 10904 this.y += s; 10905 this.z += s; 10906 10907 return this; 10908 10909 }, 10910 10911 addVectors: function ( a, b ) { 10912 10913 this.x = a.x + b.x; 10914 this.y = a.y + b.y; 10915 this.z = a.z + b.z; 10916 10917 return this; 10918 10919 }, 10920 10921 addScaledVector: function ( v, s ) { 10922 10923 this.x += v.x * s; 10924 this.y += v.y * s; 10925 this.z += v.z * s; 10926 10927 return this; 10928 10929 }, 10930 10931 sub: function ( v, w ) { 10932 10933 if ( w !== undefined ) { 10934 10935 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 10936 return this.subVectors( v, w ); 10937 10938 } 10939 10940 this.x -= v.x; 10941 this.y -= v.y; 10942 this.z -= v.z; 10943 10944 return this; 10945 10946 }, 10947 10948 subScalar: function ( s ) { 10949 10950 this.x -= s; 10951 this.y -= s; 10952 this.z -= s; 10953 10954 return this; 10955 10956 }, 10957 10958 subVectors: function ( a, b ) { 10959 10960 this.x = a.x - b.x; 10961 this.y = a.y - b.y; 10962 this.z = a.z - b.z; 10963 10964 return this; 10965 10966 }, 10967 10968 multiply: function ( v, w ) { 10969 10970 if ( w !== undefined ) { 10971 10972 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); 10973 return this.multiplyVectors( v, w ); 10974 10975 } 10976 10977 this.x *= v.x; 10978 this.y *= v.y; 10979 this.z *= v.z; 10980 10981 return this; 10982 10983 }, 10984 10985 multiplyScalar: function ( scalar ) { 10986 10987 this.x *= scalar; 10988 this.y *= scalar; 10989 this.z *= scalar; 10990 10991 return this; 10992 10993 }, 10994 10995 multiplyVectors: function ( a, b ) { 10996 10997 this.x = a.x * b.x; 10998 this.y = a.y * b.y; 10999 this.z = a.z * b.z; 11000 11001 return this; 11002 11003 }, 11004 11005 applyEuler: function () { 11006 11007 var quaternion = new Quaternion(); 11008 11009 return function applyEuler( euler ) { 11010 11011 if ( ! ( euler && euler.isEuler ) ) { 11012 11013 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); 11014 11015 } 11016 11017 return this.applyQuaternion( quaternion.setFromEuler( euler ) ); 11018 11019 }; 11020 11021 }(), 11022 11023 applyAxisAngle: function () { 11024 11025 var quaternion = new Quaternion(); 11026 11027 return function applyAxisAngle( axis, angle ) { 11028 11029 return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); 11030 11031 }; 11032 11033 }(), 11034 11035 applyMatrix3: function ( m ) { 11036 11037 var x = this.x, y = this.y, z = this.z; 11038 var e = m.elements; 11039 11040 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; 11041 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; 11042 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; 11043 11044 return this; 11045 11046 }, 11047 11048 applyMatrix4: function ( m ) { 11049 11050 var x = this.x, y = this.y, z = this.z; 11051 var e = m.elements; 11052 11053 var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); 11054 11055 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; 11056 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; 11057 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; 11058 11059 return this; 11060 11061 }, 11062 11063 applyQuaternion: function ( q ) { 11064 11065 var x = this.x, y = this.y, z = this.z; 11066 var qx = q.x, qy = q.y, qz = q.z, qw = q.w; 11067 11068 // calculate quat * vector 11069 11070 var ix = qw * x + qy * z - qz * y; 11071 var iy = qw * y + qz * x - qx * z; 11072 var iz = qw * z + qx * y - qy * x; 11073 var iw = - qx * x - qy * y - qz * z; 11074 11075 // calculate result * inverse quat 11076 11077 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; 11078 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; 11079 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; 11080 11081 return this; 11082 11083 }, 11084 11085 project: function () { 11086 11087 var matrix = new Matrix4(); 11088 11089 return function project( camera ) { 11090 11091 matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) ); 11092 return this.applyMatrix4( matrix ); 11093 11094 }; 11095 11096 }(), 11097 11098 unproject: function () { 11099 11100 var matrix = new Matrix4(); 11101 11102 return function unproject( camera ) { 11103 11104 matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) ); 11105 return this.applyMatrix4( matrix ); 11106 11107 }; 11108 11109 }(), 11110 11111 transformDirection: function ( m ) { 11112 11113 // input: THREE.Matrix4 affine matrix 11114 // vector interpreted as a direction 11115 11116 var x = this.x, y = this.y, z = this.z; 11117 var e = m.elements; 11118 11119 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; 11120 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; 11121 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; 11122 11123 return this.normalize(); 11124 11125 }, 11126 11127 divide: function ( v ) { 11128 11129 this.x /= v.x; 11130 this.y /= v.y; 11131 this.z /= v.z; 11132 11133 return this; 11134 11135 }, 11136 11137 divideScalar: function ( scalar ) { 11138 11139 return this.multiplyScalar( 1 / scalar ); 11140 11141 }, 11142 11143 min: function ( v ) { 11144 11145 this.x = Math.min( this.x, v.x ); 11146 this.y = Math.min( this.y, v.y ); 11147 this.z = Math.min( this.z, v.z ); 11148 11149 return this; 11150 11151 }, 11152 11153 max: function ( v ) { 11154 11155 this.x = Math.max( this.x, v.x ); 11156 this.y = Math.max( this.y, v.y ); 11157 this.z = Math.max( this.z, v.z ); 11158 11159 return this; 11160 11161 }, 11162 11163 clamp: function ( min, max ) { 11164 11165 // assumes min < max, componentwise 11166 11167 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 11168 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 11169 this.z = Math.max( min.z, Math.min( max.z, this.z ) ); 11170 11171 return this; 11172 11173 }, 11174 11175 clampScalar: function () { 11176 11177 var min = new Vector3(); 11178 var max = new Vector3(); 11179 11180 return function clampScalar( minVal, maxVal ) { 11181 11182 min.set( minVal, minVal, minVal ); 11183 max.set( maxVal, maxVal, maxVal ); 11184 11185 return this.clamp( min, max ); 11186 11187 }; 11188 11189 }(), 11190 11191 clampLength: function ( min, max ) { 11192 11193 var length = this.length(); 11194 11195 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 11196 11197 }, 11198 11199 floor: function () { 11200 11201 this.x = Math.floor( this.x ); 11202 this.y = Math.floor( this.y ); 11203 this.z = Math.floor( this.z ); 11204 11205 return this; 11206 11207 }, 11208 11209 ceil: function () { 11210 11211 this.x = Math.ceil( this.x ); 11212 this.y = Math.ceil( this.y ); 11213 this.z = Math.ceil( this.z ); 11214 11215 return this; 11216 11217 }, 11218 11219 round: function () { 11220 11221 this.x = Math.round( this.x ); 11222 this.y = Math.round( this.y ); 11223 this.z = Math.round( this.z ); 11224 11225 return this; 11226 11227 }, 11228 11229 roundToZero: function () { 11230 11231 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 11232 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 11233 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); 11234 11235 return this; 11236 11237 }, 11238 11239 negate: function () { 11240 11241 this.x = - this.x; 11242 this.y = - this.y; 11243 this.z = - this.z; 11244 11245 return this; 11246 11247 }, 11248 11249 dot: function ( v ) { 11250 11251 return this.x * v.x + this.y * v.y + this.z * v.z; 11252 11253 }, 11254 11255 // TODO lengthSquared? 11256 11257 lengthSq: function () { 11258 11259 return this.x * this.x + this.y * this.y + this.z * this.z; 11260 11261 }, 11262 11263 length: function () { 11264 11265 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); 11266 11267 }, 11268 11269 manhattanLength: function () { 11270 11271 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); 11272 11273 }, 11274
11275 normalize: function () { 11276 11277 return this.divideScalar( this.length() || 1 ); 11278 11279 }, 11280 11281 setLength: function ( length ) { 11282 11283 return this.normalize().multiplyScalar( length ); 11284 11285 }, 11286 11287 lerp: function ( v, alpha ) { 11288 11289 this.x += ( v.x - this.x ) * alpha; 11290 this.y += ( v.y - this.y ) * alpha; 11291 this.z += ( v.z - this.z ) * alpha; 11292 11293 return this; 11294 11295 }, 11296 11297 lerpVectors: function ( v1, v2, alpha ) { 11298 11299 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 11300 11301 }, 11302 11303 cross: function ( v, w ) { 11304 11305 if ( w !== undefined ) { 11306 11307 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); 11308 return this.crossVectors( v, w ); 11309 11310 } 11311 11312 return this.crossVectors( this, v ); 11313 11314 }, 11315 11316 crossVectors: function ( a, b ) { 11317 11318 var ax = a.x, ay = a.y, az = a.z; 11319 var bx = b.x, by = b.y, bz = b.z; 11320 11321 this.x = ay * bz - az * by; 11322 this.y = az * bx - ax * bz; 11323 this.z = ax * by - ay * bx; 11324 11325 return this; 11326 11327 }, 11328 11329 projectOnVector: function ( vector ) { 11330 11331 var scalar = vector.dot( this ) / vector.lengthSq(); 11332 11333 return this.copy( vector ).multiplyScalar( scalar ); 11334 11335 }, 11336 11337 projectOnPlane: function () { 11338 11339 var v1 = new Vector3(); 11340 11341 return function projectOnPlane( planeNormal ) { 11342 11343 v1.copy( this ).projectOnVector( planeNormal ); 11344 11345 return this.sub( v1 ); 11346 11347 }; 11348 11349 }(), 11350 11351 reflect: function () { 11352 11353 // reflect incident vector off plane orthogonal to normal 11354 // normal is assumed to have unit length 11355 11356 var v1 = new Vector3(); 11357 11358 return function reflect( normal ) { 11359 11360 return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); 11361 11362 }; 11363 11364 }(), 11365 11366 angleTo: function ( v ) { 11367 11368 var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); 11369 11370 // clamp, to handle numerical problems 11371 11372 return Math.acos( _Math.clamp( theta, - 1, 1 ) ); 11373 11374 }, 11375 11376 distanceTo: function ( v ) { 11377 11378 return Math.sqrt( this.distanceToSquared( v ) ); 11379 11380 }, 11381 11382 distanceToSquared: function ( v ) { 11383 11384 var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; 11385 11386 return dx * dx + dy * dy + dz * dz; 11387 11388 }, 11389 11390 manhattanDistanceTo: function ( v ) { 11391 11392 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); 11393 11394 }, 11395 11396 setFromSpherical: function ( s ) { 11397 11398 var sinPhiRadius = Math.sin( s.phi ) * s.radius; 11399 11400 this.x = sinPhiRadius * Math.sin( s.theta ); 11401 this.y = Math.cos( s.phi ) * s.radius; 11402 this.z = sinPhiRadius * Math.cos( s.theta ); 11403 11404 return this; 11405 11406 }, 11407 11408 setFromCylindrical: function ( c ) { 11409 11410 this.x = c.radius * Math.sin( c.theta ); 11411 this.y = c.y; 11412 this.z = c.radius * Math.cos( c.theta ); 11413 11414 return this; 11415 11416 }, 11417 11418 setFromMatrixPosition: function ( m ) { 11419 11420 var e = m.elements; 11421 11422 this.x = e[ 12 ]; 11423 this.y = e[ 13 ]; 11424 this.z = e[ 14 ]; 11425 11426 return this; 11427 11428 }, 11429 11430 setFromMatrixScale: function ( m ) { 11431 11432 var sx = this.setFromMatrixColumn( m, 0 ).length(); 11433 var sy = this.setFromMatrixColumn( m, 1 ).length(); 11434 var sz = this.setFromMatrixColumn( m, 2 ).length(); 11435 11436 this.x = sx; 11437 this.y = sy; 11438 this.z = sz; 11439 11440 return this; 11441 11442 }, 11443 11444 setFromMatrixColumn: function ( m, index ) { 11445 11446 return this.fromArray( m.elements, index * 4 ); 11447 11448 }, 11449 11450 equals: function ( v ) { 11451 11452 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); 11453 11454 }, 11455 11456 fromArray: function ( array, offset ) { 11457 11458 if ( offset === undefined ) offset = 0; 11459 11460 this.x = array[ offset ]; 11461 this.y = array[ offset + 1 ]; 11462 this.z = array[ offset + 2 ]; 11463 11464 return this; 11465 11466 }, 11467 11468 toArray: function ( array, offset ) { 11469 11470 if ( array === undefined ) array = []; 11471 if ( offset === undefined ) offset = 0; 11472 11473 array[ offset ] = this.x; 11474 array[ offset + 1 ] = this.y; 11475 array[ offset + 2 ] = this.z; 11476 11477 return array; 11478 11479 }, 11480 11481 fromBufferAttribute: function ( attribute, index, offset ) { 11482 11483 if ( offset !== undefined ) { 11484 11485 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); 11486 11487 } 11488 11489 this.x = attribute.getX( index ); 11490 this.y = attribute.getY( index ); 11491 this.z = attribute.getZ( index ); 11492 11493 return this; 11494 11495 } 11496 11497 } ); 11498 11499 /** 11500 * @author alteredq / http://alteredqualia.com/ 11501 * @author WestLangley / http://github.com/WestLangley 11502 * @author bhouston / http://clara.io 11503 * @author tschw 11504 */ 11505 11506 function Matrix3() { 11507 11508 this.elements = [ 11509 11510 1, 0, 0, 11511 0, 1, 0, 11512 0, 0, 1 11513 11514 ]; 11515 11516 if ( arguments.length > 0 ) { 11517 11518 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); 11519 11520 } 11521 11522 } 11523
vendor: 8,497 bytes, lines 11524-11924
11524 Object.assign( Matrix3.prototype, { 11525 11526 isMatrix3: true, 11527 11528 set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { 11529 11530 var te = this.elements; 11531 11532 te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; 11533 te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; 11534 te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; 11535 11536 return this; 11537 11538 }, 11539 11540 identity: function () { 11541 11542 this.set( 11543 11544 1, 0, 0, 11545 0, 1, 0, 11546 0, 0, 1 11547 11548 ); 11549 11550 return this; 11551 11552 }, 11553 11554 clone: function () { 11555 11556 return new this.constructor().fromArray( this.elements ); 11557 11558 }, 11559 11560 copy: function ( m ) { 11561 11562 var te = this.elements; 11563 var me = m.elements; 11564 11565 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; 11566 te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; 11567 te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; 11568 11569 return this; 11570 11571 }, 11572 11573 setFromMatrix4: function ( m ) { 11574 11575 var me = m.elements; 11576 11577 this.set( 11578 11579 me[ 0 ], me[ 4 ], me[ 8 ], 11580 me[ 1 ], me[ 5 ], me[ 9 ], 11581 me[ 2 ], me[ 6 ], me[ 10 ] 11582 11583 ); 11584 11585 return this; 11586 11587 }, 11588 11589 applyToBufferAttribute: function () { 11590 11591 var v1 = new Vector3(); 11592 11593 return function applyToBufferAttribute( attribute ) { 11594 11595 for ( var i = 0, l = attribute.count; i < l; i ++ ) { 11596 11597 v1.x = attribute.getX( i ); 11598 v1.y = attribute.getY( i ); 11599 v1.z = attribute.getZ( i ); 11600 11601 v1.applyMatrix3( this ); 11602 11603 attribute.setXYZ( i, v1.x, v1.y, v1.z ); 11604 11605 } 11606 11607 return attribute; 11608 11609 }; 11610 11611 }(), 11612 11613 multiply: function ( m ) { 11614 11615 return this.multiplyMatrices( this, m ); 11616 11617 }, 11618 11619 premultiply: function ( m ) { 11620 11621 return this.multiplyMatrices( m, this ); 11622 11623 }, 11624 11625 multiplyMatrices: function ( a, b ) { 11626 11627 var ae = a.elements; 11628 var be = b.elements; 11629 var te = this.elements; 11630 11631 var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; 11632 var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; 11633 var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; 11634 11635 var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; 11636 var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; 11637 var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; 11638 11639 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; 11640 te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; 11641 te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; 11642 11643 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; 11644 te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; 11645 te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; 11646 11647 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; 11648 te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; 11649 te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; 11650 11651 return this; 11652 11653 }, 11654 11655 multiplyScalar: function ( s ) { 11656 11657 var te = this.elements; 11658 11659 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; 11660 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; 11661 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; 11662 11663 return this; 11664 11665 }, 11666 11667 determinant: function () { 11668 11669 var te = this.elements; 11670 11671 var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], 11672 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], 11673 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; 11674 11675 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; 11676 11677 }, 11678 11679 getInverse: function ( matrix, throwOnDegenerate ) { 11680 11681 if ( matrix && matrix.isMatrix4 ) { 11682 11683 console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); 11684 11685 } 11686 11687 var me = matrix.elements, 11688 te = this.elements, 11689 11690 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], 11691 n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], 11692 n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], 11693 11694 t11 = n33 * n22 - n32 * n23, 11695 t12 = n32 * n13 - n33 * n12, 11696 t13 = n23 * n12 - n22 * n13, 11697 11698 det = n11 * t11 + n21 * t12 + n31 * t13; 11699 11700 if ( det === 0 ) { 11701 11702 var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; 11703 11704 if ( throwOnDegenerate === true ) { 11705 11706 throw new Error( msg ); 11707 11708 } else { 11709 11710 console.warn( msg ); 11711 11712 } 11713 11714 return this.identity(); 11715 11716 } 11717 11718 var detInv = 1 / det; 11719 11720 te[ 0 ] = t11 * detInv; 11721 te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; 11722 te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; 11723 11724 te[ 3 ] = t12 * detInv; 11725 te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; 11726 te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; 11727 11728 te[ 6 ] = t13 * detInv; 11729 te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; 11730 te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; 11731 11732 return this; 11733 11734 }, 11735 11736 transpose: function () { 11737 11738 var tmp, m = this.elements; 11739 11740 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; 11741 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; 11742 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; 11743 11744 return this; 11745 11746 }, 11747 11748 getNormalMatrix: function ( matrix4 ) { 11749 11750 return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); 11751 11752 }, 11753 11754 transposeIntoArray: function ( r ) { 11755 11756 var m = this.elements; 11757 11758 r[ 0 ] = m[ 0 ]; 11759 r[ 1 ] = m[ 3 ]; 11760 r[ 2 ] = m[ 6 ]; 11761 r[ 3 ] = m[ 1 ]; 11762 r[ 4 ] = m[ 4 ]; 11763 r[ 5 ] = m[ 7 ]; 11764 r[ 6 ] = m[ 2 ]; 11765 r[ 7 ] = m[ 5 ]; 11766 r[ 8 ] = m[ 8 ]; 11767 11768 return this; 11769 11770 }, 11771 11772 setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { 11773 11774 var c = Math.cos( rotation ); 11775 var s = Math.sin( rotation ); 11776 11777 this.set( 11778 sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, 11779 - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, 11780 0, 0, 1 11781 ); 11782 11783 }, 11784 11785 scale: function ( sx, sy ) { 11786 11787 var te = this.elements; 11788 11789 te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; 11790 te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; 11791 11792 return this; 11793 11794 }, 11795 11796 rotate: function ( theta ) { 11797 11798 var c = Math.cos( theta ); 11799 var s = Math.sin( theta ); 11800 11801 var te = this.elements; 11802 11803 var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; 11804 var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; 11805 11806 te[ 0 ] = c * a11 + s * a21; 11807 te[ 3 ] = c * a12 + s * a22; 11808 te[ 6 ] = c * a13 + s * a23; 11809 11810 te[ 1 ] = - s * a11 + c * a21; 11811 te[ 4 ] = - s * a12 + c * a22; 11812 te[ 7 ] = - s * a13 + c * a23; 11813 11814 return this; 11815 11816 }, 11817 11818 translate: function ( tx, ty ) { 11819 11820 var te = this.elements; 11821 11822 te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; 11823 te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; 11824 11825 return this; 11826 11827 }, 11828 11829 equals: function ( matrix ) { 11830 11831 var te = this.elements; 11832 var me = matrix.elements; 11833 11834 for ( var i = 0; i < 9; i ++ ) { 11835 11836 if ( te[ i ] !== me[ i ] ) return false; 11837 11838 } 11839 11840 return true; 11841 11842 }, 11843 11844 fromArray: function ( array, offset ) { 11845 11846 if ( offset === undefined ) offset = 0; 11847 11848 for ( var i = 0; i < 9; i ++ ) { 11849 11850 this.elements[ i ] = array[ i + offset ]; 11851 11852 } 11853 11854 return this; 11855 11856 }, 11857 11858 toArray: function ( array, offset ) { 11859 11860 if ( array === undefined ) array = []; 11861 if ( offset === undefined ) offset = 0; 11862 11863 var te = this.elements; 11864 11865 array[ offset ] = te[ 0 ]; 11866 array[ offset + 1 ] = te[ 1 ]; 11867 array[ offset + 2 ] = te[ 2 ]; 11868 11869 array[ offset + 3 ] = te[ 3 ]; 11870 array[ offset + 4 ] = te[ 4 ]; 11871 array[ offset + 5 ] = te[ 5 ]; 11872 11873 array[ offset + 6 ] = te[ 6 ]; 11874 array[ offset + 7 ] = te[ 7 ]; 11875 array[ offset + 8 ] = te[ 8 ]; 11876 11877 return array; 11878 11879 } 11880 11881 } ); 11882 11883 /** 11884 * @author mrdoob / http://mrdoob.com/ 11885 * @author alteredq / http://alteredqualia.com/ 11886 * @author szimek / https://github.com/szimek/ 11887 */ 11888 11889 var textureId = 0; 11890 11891 function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { 11892 11893 Object.defineProperty( this, 'id', { value: textureId ++ } ); 11894 11895 this.uuid = _Math.generateUUID(); 11896 11897 this.name = ''; 11898 11899 this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; 11900 this.mipmaps = []; 11901 11902 this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; 11903 11904 this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; 11905 this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; 11906 11907 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; 11908 this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter; 11909 11910 this.anisotropy = anisotropy !== undefined ? anisotropy : 1; 11911 11912 this.format = format !== undefined ? format : RGBAFormat; 11913 this.type = type !== undefined ? type : UnsignedByteType; 11914 11915 this.offset = new Vector2( 0, 0 ); 11916 this.repeat = new Vector2( 1, 1 ); 11917 this.center = new Vector2( 0, 0 ); 11918 this.rotation = 0; 11919 11920 this.matrixAutoUpdate = true; 11921 this.matrix = new Matrix3(); 11922 11923 this.generateMipmaps = true; 11924 this.premultiplyAlpha = false;
11925 this.flipY = true; 11926 this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) 11927 11928 // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. 11929 // 11930 // Also changing the encoding after already used by a Material will not automatically make the Material 11931 // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. 11932 this.encoding = encoding !== undefined ? encoding : LinearEncoding; 11933 11934 this.version = 0; 11935 this.onUpdate = null; 11936 11937 } 11938 11939 Texture.DEFAULT_IMAGE = undefined; 11940 Texture.DEFAULT_MAPPING = UVMapping; 11941 11942 Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 11943 11944 constructor: Texture, 11945 11946 isTexture: true, 11947 11948 updateMatrix: function () { 11949 11950 this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); 11951 11952 }, 11953 11954 clone: function () { 11955 11956 return new this.constructor().copy( this ); 11957 11958 }, 11959 11960 copy: function ( source ) { 11961 11962 this.name = source.name; 11963 11964 this.image = source.image; 11965 this.mipmaps = source.mipmaps.slice( 0 ); 11966 11967 this.mapping = source.mapping; 11968 11969 this.wrapS = source.wrapS; 11970 this.wrapT = source.wrapT; 11971 11972 this.magFilter = source.magFilter; 11973 this.minFilter = source.minFilter; 11974 11975 this.anisotropy = source.anisotropy; 11976 11977 this.format = source.format; 11978 this.type = source.type; 11979 11980 this.offset.copy( source.offset ); 11981 this.repeat.copy( source.repeat ); 11982 this.center.copy( source.center ); 11983 this.rotation = source.rotation; 11984 11985 this.matrixAutoUpdate = source.matrixAutoUpdate; 11986 this.matrix.copy( source.matrix ); 11987 11988 this.generateMipmaps = source.generateMipmaps; 11989 this.premultiplyAlpha = source.premultiplyAlpha; 11990 this.flipY = source.flipY; 11991 this.unpackAlignment = source.unpackAlignment; 11992 this.encoding = source.encoding; 11993 11994 return this; 11995 11996 }, 11997 11998 toJSON: function ( meta ) { 11999 12000 var isRootObject = ( meta === undefined || typeof meta === 'string' ); 12001 12002 if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { 12003 12004 return meta.textures[ this.uuid ]; 12005 12006 } 12007 12008 function getDataURL( image ) { 12009 12010 var canvas; 12011 12012 if ( image instanceof HTMLCanvasElement ) { 12013 12014 canvas = image; 12015 12016 } else { 12017 12018 canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 12019 canvas.width = image.width; 12020 canvas.height = image.height; 12021 12022 var context = canvas.getContext( '2d' ); 12023 12024 if ( image instanceof ImageData ) { 12025 12026 context.putImageData( image, 0, 0 ); 12027 12028 } else { 12029 12030 context.drawImage( image, 0, 0, image.width, image.height ); 12031 12032 } 12033 12034 } 12035 12036 if ( canvas.width > 2048 || canvas.height > 2048 ) { 12037 12038 return canvas.toDataURL( 'image/jpeg', 0.6 ); 12039 12040 } else { 12041 12042 return canvas.toDataURL( 'image/png' ); 12043 12044 } 12045 12046 } 12047 12048 var output = { 12049 12050 metadata: { 12051 version: 4.5, 12052 type: 'Texture', 12053 generator: 'Texture.toJSON' 12054 }, 12055 12056 uuid: this.uuid, 12057 name: this.name, 12058 12059 mapping: this.mapping, 12060 12061 repeat: [ this.repeat.x, this.repeat.y ], 12062 offset: [ this.offset.x, this.offset.y ], 12063 center: [ this.center.x, this.center.y ], 12064 rotation: this.rotation, 12065 12066 wrap: [ this.wrapS, this.wrapT ], 12067 12068 format: this.format, 12069 minFilter: this.minFilter, 12070 magFilter: this.magFilter, 12071 anisotropy: this.anisotropy, 12072 12073 flipY: this.flipY 12074 12075 }; 12076 12077 if ( this.image !== undefined ) { 12078 12079 // TODO: Move to THREE.Image 12080 12081 var image = this.image; 12082 12083 if ( image.uuid === undefined ) { 12084 12085 image.uuid = _Math.generateUUID(); // UGH 12086 12087 } 12088 12089 if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { 12090 12091 meta.images[ image.uuid ] = { 12092 uuid: image.uuid, 12093 url: getDataURL( image ) 12094 }; 12095 12096 } 12097 12098 output.image = image.uuid; 12099 12100 } 12101 12102 if ( ! isRootObject ) { 12103 12104 meta.textures[ this.uuid ] = output; 12105 12106 } 12107 12108 return output; 12109 12110 }, 12111 12112 dispose: function () { 12113 12114 this.dispatchEvent( { type: 'dispose' } ); 12115 12116 }, 12117
vendor: 27,117 bytes, lines 12118-13429
12118 transformUv: function ( uv ) { 12119 12120 if ( this.mapping !== UVMapping ) return; 12121 12122 uv.applyMatrix3( this.matrix ); 12123 12124 if ( uv.x < 0 || uv.x > 1 ) { 12125 12126 switch ( this.wrapS ) { 12127 12128 case RepeatWrapping: 12129 12130 uv.x = uv.x - Math.floor( uv.x ); 12131 break; 12132 12133 case ClampToEdgeWrapping: 12134 12135 uv.x = uv.x < 0 ? 0 : 1; 12136 break; 12137 12138 case MirroredRepeatWrapping: 12139 12140 if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { 12141 12142 uv.x = Math.ceil( uv.x ) - uv.x; 12143 12144 } else { 12145 12146 uv.x = uv.x - Math.floor( uv.x ); 12147 12148 } 12149 break; 12150 12151 } 12152 12153 } 12154 12155 if ( uv.y < 0 || uv.y > 1 ) { 12156 12157 switch ( this.wrapT ) { 12158 12159 case RepeatWrapping: 12160 12161 uv.y = uv.y - Math.floor( uv.y ); 12162 break; 12163 12164 case ClampToEdgeWrapping: 12165 12166 uv.y = uv.y < 0 ? 0 : 1; 12167 break; 12168 12169 case MirroredRepeatWrapping: 12170 12171 if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { 12172 12173 uv.y = Math.ceil( uv.y ) - uv.y; 12174 12175 } else { 12176 12177 uv.y = uv.y - Math.floor( uv.y ); 12178 12179 } 12180 break; 12181 12182 } 12183 12184 } 12185 12186 if ( this.flipY ) { 12187 12188 uv.y = 1 - uv.y; 12189 12190 } 12191 12192 } 12193 12194 } ); 12195 12196 Object.defineProperty( Texture.prototype, "needsUpdate", { 12197 12198 set: function ( value ) { 12199 12200 if ( value === true ) this.version ++; 12201 12202 } 12203 12204 } ); 12205 12206 /** 12207 * @author supereggbert / http://www.paulbrunt.co.uk/ 12208 * @author philogb / http://blog.thejit.org/ 12209 * @author mikael emtinger / http://gomo.se/ 12210 * @author egraether / http://egraether.com/ 12211 * @author WestLangley / http://github.com/WestLangley 12212 */ 12213 12214 function Vector4( x, y, z, w ) { 12215 12216 this.x = x || 0; 12217 this.y = y || 0; 12218 this.z = z || 0; 12219 this.w = ( w !== undefined ) ? w : 1; 12220 12221 } 12222 12223 Object.assign( Vector4.prototype, { 12224 12225 isVector4: true, 12226 12227 set: function ( x, y, z, w ) { 12228 12229 this.x = x; 12230 this.y = y; 12231 this.z = z; 12232 this.w = w; 12233 12234 return this; 12235 12236 }, 12237 12238 setScalar: function ( scalar ) { 12239 12240 this.x = scalar; 12241 this.y = scalar; 12242 this.z = scalar; 12243 this.w = scalar; 12244 12245 return this; 12246 12247 }, 12248 12249 setX: function ( x ) { 12250 12251 this.x = x; 12252 12253 return this; 12254 12255 }, 12256 12257 setY: function ( y ) { 12258 12259 this.y = y; 12260 12261 return this; 12262 12263 }, 12264 12265 setZ: function ( z ) { 12266 12267 this.z = z; 12268 12269 return this; 12270 12271 }, 12272 12273 setW: function ( w ) { 12274 12275 this.w = w; 12276 12277 return this; 12278 12279 }, 12280 12281 setComponent: function ( index, value ) { 12282 12283 switch ( index ) { 12284 12285 case 0: this.x = value; break; 12286 case 1: this.y = value; break; 12287 case 2: this.z = value; break; 12288 case 3: this.w = value; break; 12289 default: throw new Error( 'index is out of range: ' + index ); 12290 12291 } 12292 12293 return this; 12294 12295 }, 12296 12297 getComponent: function ( index ) { 12298 12299 switch ( index ) { 12300 12301 case 0: return this.x; 12302 case 1: return this.y; 12303 case 2: return this.z; 12304 case 3: return this.w; 12305 default: throw new Error( 'index is out of range: ' + index ); 12306 12307 } 12308 12309 }, 12310 12311 clone: function () { 12312 12313 return new this.constructor( this.x, this.y, this.z, this.w ); 12314 12315 }, 12316 12317 copy: function ( v ) { 12318 12319 this.x = v.x; 12320 this.y = v.y; 12321 this.z = v.z; 12322 this.w = ( v.w !== undefined ) ? v.w : 1; 12323 12324 return this; 12325 12326 }, 12327 12328 add: function ( v, w ) { 12329 12330 if ( w !== undefined ) { 12331 12332 console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); 12333 return this.addVectors( v, w ); 12334 12335 } 12336 12337 this.x += v.x; 12338 this.y += v.y; 12339 this.z += v.z; 12340 this.w += v.w; 12341 12342 return this; 12343 12344 }, 12345 12346 addScalar: function ( s ) { 12347 12348 this.x += s; 12349 this.y += s; 12350 this.z += s; 12351 this.w += s; 12352 12353 return this; 12354 12355 }, 12356 12357 addVectors: function ( a, b ) { 12358 12359 this.x = a.x + b.x; 12360 this.y = a.y + b.y; 12361 this.z = a.z + b.z; 12362 this.w = a.w + b.w; 12363 12364 return this; 12365 12366 }, 12367 12368 addScaledVector: function ( v, s ) { 12369 12370 this.x += v.x * s; 12371 this.y += v.y * s; 12372 this.z += v.z * s; 12373 this.w += v.w * s; 12374 12375 return this; 12376 12377 }, 12378 12379 sub: function ( v, w ) { 12380 12381 if ( w !== undefined ) { 12382 12383 console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); 12384 return this.subVectors( v, w ); 12385 12386 } 12387 12388 this.x -= v.x; 12389 this.y -= v.y; 12390 this.z -= v.z; 12391 this.w -= v.w; 12392 12393 return this; 12394 12395 }, 12396 12397 subScalar: function ( s ) { 12398 12399 this.x -= s; 12400 this.y -= s; 12401 this.z -= s; 12402 this.w -= s; 12403 12404 return this; 12405 12406 }, 12407 12408 subVectors: function ( a, b ) { 12409 12410 this.x = a.x - b.x; 12411 this.y = a.y - b.y; 12412 this.z = a.z - b.z; 12413 this.w = a.w - b.w; 12414 12415 return this; 12416 12417 }, 12418 12419 multiplyScalar: function ( scalar ) { 12420 12421 this.x *= scalar; 12422 this.y *= scalar; 12423 this.z *= scalar; 12424 this.w *= scalar; 12425 12426 return this; 12427 12428 }, 12429 12430 applyMatrix4: function ( m ) { 12431 12432 var x = this.x, y = this.y, z = this.z, w = this.w; 12433 var e = m.elements; 12434 12435 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; 12436 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; 12437 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; 12438 this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; 12439 12440 return this; 12441 12442 }, 12443 12444 divideScalar: function ( scalar ) { 12445 12446 return this.multiplyScalar( 1 / scalar ); 12447 12448 }, 12449 12450 setAxisAngleFromQuaternion: function ( q ) { 12451 12452 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm 12453 12454 // q is assumed to be normalized 12455 12456 this.w = 2 * Math.acos( q.w ); 12457 12458 var s = Math.sqrt( 1 - q.w * q.w ); 12459 12460 if ( s < 0.0001 ) { 12461 12462 this.x = 1; 12463 this.y = 0; 12464 this.z = 0; 12465 12466 } else { 12467 12468 this.x = q.x / s; 12469 this.y = q.y / s; 12470 this.z = q.z / s; 12471 12472 } 12473 12474 return this; 12475 12476 }, 12477 12478 setAxisAngleFromRotationMatrix: function ( m ) { 12479 12480 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm 12481 12482 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 12483 12484 var angle, x, y, z, // variables for result 12485 epsilon = 0.01, // margin to allow for rounding errors 12486 epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees 12487 12488 te = m.elements, 12489 12490 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], 12491 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], 12492 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; 12493 12494 if ( ( Math.abs( m12 - m21 ) < epsilon ) && 12495 ( Math.abs( m13 - m31 ) < epsilon ) && 12496 ( Math.abs( m23 - m32 ) < epsilon ) ) { 12497 12498 // singularity found 12499 // first check for identity matrix which must have +1 for all terms 12500 // in leading diagonal and zero in other terms 12501 12502 if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && 12503 ( Math.abs( m13 + m31 ) < epsilon2 ) && 12504 ( Math.abs( m23 + m32 ) < epsilon2 ) && 12505 ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { 12506 12507 // this singularity is identity matrix so angle = 0 12508 12509 this.set( 1, 0, 0, 0 ); 12510 12511 return this; // zero angle, arbitrary axis 12512 12513 } 12514 12515 // otherwise this singularity is angle = 180 12516 12517 angle = Math.PI; 12518 12519 var xx = ( m11 + 1 ) / 2; 12520 var yy = ( m22 + 1 ) / 2; 12521 var zz = ( m33 + 1 ) / 2; 12522 var xy = ( m12 + m21 ) / 4; 12523 var xz = ( m13 + m31 ) / 4; 12524 var yz = ( m23 + m32 ) / 4; 12525 12526 if ( ( xx > yy ) && ( xx > zz ) ) { 12527 12528 // m11 is the largest diagonal term 12529 12530 if ( xx < epsilon ) { 12531 12532 x = 0; 12533 y = 0.707106781; 12534 z = 0.707106781; 12535 12536 } else { 12537 12538 x = Math.sqrt( xx ); 12539 y = xy / x; 12540 z = xz / x; 12541 12542 } 12543 12544 } else if ( yy > zz ) { 12545 12546 // m22 is the largest diagonal term 12547 12548 if ( yy < epsilon ) { 12549 12550 x = 0.707106781; 12551 y = 0; 12552 z = 0.707106781; 12553 12554 } else { 12555 12556 y = Math.sqrt( yy ); 12557 x = xy / y; 12558 z = yz / y; 12559 12560 } 12561 12562 } else { 12563 12564 // m33 is the largest diagonal term so base result on this 12565 12566 if ( zz < epsilon ) { 12567 12568 x = 0.707106781; 12569 y = 0.707106781; 12570 z = 0; 12571 12572 } else { 12573 12574 z = Math.sqrt( zz ); 12575 x = xz / z; 12576 y = yz / z; 12577 12578 } 12579 12580 } 12581 12582 this.set( x, y, z, angle ); 12583 12584 return this; // return 180 deg rotation 12585 12586 } 12587 12588 // as we have reached here there are no singularities so we can handle normally 12589 12590 var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + 12591 ( m13 - m31 ) * ( m13 - m31 ) + 12592 ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize 12593 12594 if ( Math.abs( s ) < 0.001 ) s = 1; 12595 12596 // prevent divide by zero, should not happen if matrix is orthogonal and should be 12597 // caught by singularity test above, but I've left it in just in case 12598 12599 this.x = ( m32 - m23 ) / s; 12600 this.y = ( m13 - m31 ) / s; 12601 this.z = ( m21 - m12 ) / s; 12602 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); 12603 12604 return this; 12605 12606 }, 12607 12608 min: function ( v ) { 12609 12610 this.x = Math.min( this.x, v.x ); 12611 this.y = Math.min( this.y, v.y ); 12612 this.z = Math.min( this.z, v.z ); 12613 this.w = Math.min( this.w, v.w ); 12614 12615 return this; 12616 12617 }, 12618 12619 max: function ( v ) { 12620 12621 this.x = Math.max( this.x, v.x ); 12622 this.y = Math.max( this.y, v.y ); 12623 this.z = Math.max( this.z, v.z ); 12624 this.w = Math.max( this.w, v.w ); 12625 12626 return this; 12627 12628 }, 12629 12630 clamp: function ( min, max ) { 12631 12632 // assumes min < max, componentwise 12633 12634 this.x = Math.max( min.x, Math.min( max.x, this.x ) ); 12635 this.y = Math.max( min.y, Math.min( max.y, this.y ) ); 12636 this.z = Math.max( min.z, Math.min( max.z, this.z ) ); 12637 this.w = Math.max( min.w, Math.min( max.w, this.w ) ); 12638 12639 return this; 12640 12641 }, 12642 12643 clampScalar: function () { 12644 12645 var min, max; 12646 12647 return function clampScalar( minVal, maxVal ) { 12648 12649 if ( min === undefined ) { 12650 12651 min = new Vector4(); 12652 max = new Vector4(); 12653 12654 } 12655 12656 min.set( minVal, minVal, minVal, minVal ); 12657 max.set( maxVal, maxVal, maxVal, maxVal ); 12658 12659 return this.clamp( min, max ); 12660 12661 }; 12662 12663 }(), 12664 12665 clampLength: function ( min, max ) { 12666 12667 var length = this.length(); 12668 12669 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); 12670 12671 }, 12672 12673 floor: function () { 12674 12675 this.x = Math.floor( this.x ); 12676 this.y = Math.floor( this.y ); 12677 this.z = Math.floor( this.z ); 12678 this.w = Math.floor( this.w ); 12679 12680 return this; 12681 12682 }, 12683 12684 ceil: function () { 12685 12686 this.x = Math.ceil( this.x ); 12687 this.y = Math.ceil( this.y ); 12688 this.z = Math.ceil( this.z ); 12689 this.w = Math.ceil( this.w ); 12690 12691 return this; 12692 12693 }, 12694 12695 round: function () { 12696 12697 this.x = Math.round( this.x ); 12698 this.y = Math.round( this.y ); 12699 this.z = Math.round( this.z ); 12700 this.w = Math.round( this.w ); 12701 12702 return this; 12703 12704 }, 12705 12706 roundToZero: function () { 12707 12708 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); 12709 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); 12710 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); 12711 this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); 12712 12713 return this; 12714 12715 }, 12716 12717 negate: function () { 12718 12719 this.x = - this.x; 12720 this.y = - this.y; 12721 this.z = - this.z; 12722 this.w = - this.w; 12723 12724 return this; 12725 12726 }, 12727 12728 dot: function ( v ) { 12729 12730 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; 12731 12732 }, 12733 12734 lengthSq: function () { 12735 12736 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; 12737 12738 }, 12739 12740 length: function () { 12741 12742 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); 12743 12744 }, 12745 12746 manhattanLength: function () { 12747 12748 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); 12749 12750 }, 12751 12752 normalize: function () { 12753 12754 return this.divideScalar( this.length() || 1 ); 12755 12756 }, 12757 12758 setLength: function ( length ) { 12759 12760 return this.normalize().multiplyScalar( length ); 12761 12762 }, 12763 12764 lerp: function ( v, alpha ) { 12765 12766 this.x += ( v.x - this.x ) * alpha; 12767 this.y += ( v.y - this.y ) * alpha; 12768 this.z += ( v.z - this.z ) * alpha; 12769 this.w += ( v.w - this.w ) * alpha; 12770 12771 return this; 12772 12773 }, 12774 12775 lerpVectors: function ( v1, v2, alpha ) { 12776 12777 return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); 12778 12779 }, 12780 12781 equals: function ( v ) { 12782 12783 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); 12784 12785 }, 12786 12787 fromArray: function ( array, offset ) { 12788 12789 if ( offset === undefined ) offset = 0; 12790 12791 this.x = array[ offset ]; 12792 this.y = array[ offset + 1 ]; 12793 this.z = array[ offset + 2 ]; 12794 this.w = array[ offset + 3 ]; 12795 12796 return this; 12797 12798 }, 12799 12800 toArray: function ( array, offset ) { 12801 12802 if ( array === undefined ) array = []; 12803 if ( offset === undefined ) offset = 0; 12804 12805 array[ offset ] = this.x; 12806 array[ offset + 1 ] = this.y; 12807 array[ offset + 2 ] = this.z; 12808 array[ offset + 3 ] = this.w; 12809 12810 return array; 12811 12812 }, 12813 12814 fromBufferAttribute: function ( attribute, index, offset ) { 12815 12816 if ( offset !== undefined ) { 12817 12818 console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); 12819 12820 } 12821 12822 this.x = attribute.getX( index ); 12823 this.y = attribute.getY( index ); 12824 this.z = attribute.getZ( index ); 12825 this.w = attribute.getW( index ); 12826 12827 return this; 12828 12829 } 12830 12831 } ); 12832 12833 /** 12834 * @author szimek / https://github.com/szimek/ 12835 * @author alteredq / http://alteredqualia.com/ 12836 * @author Marius Kintel / https://github.com/kintel 12837 */ 12838 12839 /* 12840 In options, we can specify: 12841 * Texture parameters for an auto-generated target texture 12842 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers 12843 */ 12844 function WebGLRenderTarget( width, height, options ) { 12845 12846 this.width = width; 12847 this.height = height; 12848 12849 this.scissor = new Vector4( 0, 0, width, height ); 12850 this.scissorTest = false; 12851 12852 this.viewport = new Vector4( 0, 0, width, height ); 12853 12854 options = options || {}; 12855 12856 if ( options.minFilter === undefined ) options.minFilter = LinearFilter; 12857 12858 this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); 12859 12860 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : true; 12861 12862 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; 12863 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; 12864 this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; 12865 12866 } 12867 12868 WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 12869 12870 constructor: WebGLRenderTarget, 12871 12872 isWebGLRenderTarget: true, 12873 12874 setSize: function ( width, height ) { 12875 12876 if ( this.width !== width || this.height !== height ) { 12877 12878 this.width = width; 12879 this.height = height; 12880 12881 this.dispose(); 12882 12883 } 12884 12885 this.viewport.set( 0, 0, width, height ); 12886 this.scissor.set( 0, 0, width, height ); 12887 12888 }, 12889 12890 clone: function () { 12891 12892 return new this.constructor().copy( this ); 12893 12894 }, 12895 12896 copy: function ( source ) { 12897 12898 this.width = source.width; 12899 this.height = source.height; 12900 12901 this.viewport.copy( source.viewport ); 12902 12903 this.texture = source.texture.clone(); 12904 12905 this.depthBuffer = source.depthBuffer; 12906 this.stencilBuffer = source.stencilBuffer; 12907 this.depthTexture = source.depthTexture; 12908 12909 return this; 12910 12911 }, 12912 12913 dispose: function () { 12914 12915 this.dispatchEvent( { type: 'dispose' } ); 12916 12917 } 12918 12919 } ); 12920 12921 /** 12922 * @author alteredq / http://alteredqualia.com 12923 */ 12924 12925 function WebGLRenderTargetCube( width, height, options ) { 12926 12927 WebGLRenderTarget.call( this, width, height, options ); 12928 12929 this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 12930 this.activeMipMapLevel = 0; 12931 12932 } 12933 12934 WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); 12935 WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; 12936 12937 WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; 12938 12939 /** 12940 * @author alteredq / http://alteredqualia.com/ 12941 */ 12942 12943 function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { 12944 12945 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 12946 12947 this.image = { data: data, width: width, height: height }; 12948 12949 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; 12950 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; 12951 12952 this.generateMipmaps = false; 12953 this.flipY = false; 12954 this.unpackAlignment = 1; 12955 12956 } 12957 12958 DataTexture.prototype = Object.create( Texture.prototype ); 12959 DataTexture.prototype.constructor = DataTexture; 12960 12961 DataTexture.prototype.isDataTexture = true; 12962 12963 /** 12964 * @author bhouston / http://clara.io 12965 * @author WestLangley / http://github.com/WestLangley 12966 */ 12967 12968 function Box3( min, max ) { 12969 12970 this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); 12971 this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); 12972 12973 } 12974 12975 Object.assign( Box3.prototype, { 12976 12977 isBox3: true, 12978 12979 set: function ( min, max ) { 12980 12981 this.min.copy( min ); 12982 this.max.copy( max ); 12983 12984 return this; 12985 12986 }, 12987 12988 setFromArray: function ( array ) { 12989 12990 var minX = + Infinity; 12991 var minY = + Infinity; 12992 var minZ = + Infinity; 12993 12994 var maxX = - Infinity; 12995 var maxY = - Infinity; 12996 var maxZ = - Infinity; 12997 12998 for ( var i = 0, l = array.length; i < l; i += 3 ) { 12999 13000 var x = array[ i ]; 13001 var y = array[ i + 1 ]; 13002 var z = array[ i + 2 ]; 13003 13004 if ( x < minX ) minX = x; 13005 if ( y < minY ) minY = y; 13006 if ( z < minZ ) minZ = z; 13007 13008 if ( x > maxX ) maxX = x; 13009 if ( y > maxY ) maxY = y; 13010 if ( z > maxZ ) maxZ = z; 13011 13012 } 13013 13014 this.min.set( minX, minY, minZ ); 13015 this.max.set( maxX, maxY, maxZ ); 13016 13017 return this; 13018 13019 }, 13020 13021 setFromBufferAttribute: function ( attribute ) { 13022 13023 var minX = + Infinity; 13024 var minY = + Infinity; 13025 var minZ = + Infinity; 13026 13027 var maxX = - Infinity; 13028 var maxY = - Infinity; 13029 var maxZ = - Infinity; 13030 13031 for ( var i = 0, l = attribute.count; i < l; i ++ ) { 13032 13033 var x = attribute.getX( i ); 13034 var y = attribute.getY( i ); 13035 var z = attribute.getZ( i ); 13036 13037 if ( x < minX ) minX = x; 13038 if ( y < minY ) minY = y; 13039 if ( z < minZ ) minZ = z; 13040 13041 if ( x > maxX ) maxX = x; 13042 if ( y > maxY ) maxY = y; 13043 if ( z > maxZ ) maxZ = z; 13044 13045 } 13046 13047 this.min.set( minX, minY, minZ ); 13048 this.max.set( maxX, maxY, maxZ ); 13049 13050 return this; 13051 13052 }, 13053 13054 setFromPoints: function ( points ) { 13055 13056 this.makeEmpty(); 13057 13058 for ( var i = 0, il = points.length; i < il; i ++ ) { 13059 13060 this.expandByPoint( points[ i ] ); 13061 13062 } 13063 13064 return this; 13065 13066 }, 13067 13068 setFromCenterAndSize: function () { 13069 13070 var v1 = new Vector3(); 13071 13072 return function setFromCenterAndSize( center, size ) { 13073 13074 var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); 13075 13076 this.min.copy( center ).sub( halfSize ); 13077 this.max.copy( center ).add( halfSize ); 13078 13079 return this; 13080 13081 }; 13082 13083 }(), 13084 13085 setFromObject: function ( object ) { 13086 13087 this.makeEmpty(); 13088 13089 return this.expandByObject( object ); 13090 13091 }, 13092 13093 clone: function () { 13094 13095 return new this.constructor().copy( this ); 13096 13097 }, 13098 13099 copy: function ( box ) { 13100 13101 this.min.copy( box.min ); 13102 this.max.copy( box.max ); 13103 13104 return this; 13105 13106 }, 13107 13108 makeEmpty: function () { 13109 13110 this.min.x = this.min.y = this.min.z = + Infinity; 13111 this.max.x = this.max.y = this.max.z = - Infinity; 13112 13113 return this; 13114 13115 }, 13116 13117 isEmpty: function () { 13118 13119 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 13120 13121 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); 13122 13123 }, 13124 13125 getCenter: function ( target ) { 13126 13127 if ( target === undefined ) { 13128 13129 console.warn( 'THREE.Box3: .getCenter() target is now required' ); 13130 target = new Vector3(); 13131 13132 } 13133 13134 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); 13135 13136 }, 13137 13138 getSize: function ( target ) { 13139 13140 if ( target === undefined ) { 13141 13142 console.warn( 'THREE.Box3: .getSize() target is now required' ); 13143 target = new Vector3(); 13144 13145 } 13146 13147 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); 13148 13149 }, 13150 13151 expandByPoint: function ( point ) { 13152 13153 this.min.min( point ); 13154 this.max.max( point ); 13155 13156 return this; 13157 13158 }, 13159 13160 expandByVector: function ( vector ) { 13161 13162 this.min.sub( vector ); 13163 this.max.add( vector ); 13164 13165 return this; 13166 13167 }, 13168 13169 expandByScalar: function ( scalar ) { 13170 13171 this.min.addScalar( - scalar ); 13172 this.max.addScalar( scalar ); 13173 13174 return this; 13175 13176 }, 13177 13178 expandByObject: function () { 13179 13180 // Computes the world-axis-aligned bounding box of an object (including its children), 13181 // accounting for both the object's, and children's, world transforms 13182 13183 var scope, i, l; 13184 13185 var v1 = new Vector3(); 13186 13187 function traverse( node ) { 13188 13189 var geometry = node.geometry; 13190 13191 if ( geometry !== undefined ) { 13192 13193 if ( geometry.isGeometry ) { 13194 13195 var vertices = geometry.vertices; 13196 13197 for ( i = 0, l = vertices.length; i < l; i ++ ) { 13198 13199 v1.copy( vertices[ i ] ); 13200 v1.applyMatrix4( node.matrixWorld ); 13201 13202 scope.expandByPoint( v1 ); 13203 13204 } 13205 13206 } else if ( geometry.isBufferGeometry ) { 13207 13208 var attribute = geometry.attributes.position; 13209 13210 if ( attribute !== undefined ) { 13211 13212 for ( i = 0, l = attribute.count; i < l; i ++ ) { 13213 13214 v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); 13215 13216 scope.expandByPoint( v1 ); 13217 13218 } 13219 13220 } 13221 13222 } 13223 13224 } 13225 13226 } 13227 13228 return function expandByObject( object ) { 13229 13230 scope = this; 13231 13232 object.updateMatrixWorld( true ); 13233 13234 object.traverse( traverse ); 13235 13236 return this; 13237 13238 }; 13239 13240 }(), 13241 13242 containsPoint: function ( point ) { 13243 13244 return point.x < this.min.x || point.x > this.max.x || 13245 point.y < this.min.y || point.y > this.max.y || 13246 point.z < this.min.z || point.z > this.max.z ? false : true; 13247 13248 }, 13249 13250 containsBox: function ( box ) { 13251 13252 return this.min.x <= box.min.x && box.max.x <= this.max.x && 13253 this.min.y <= box.min.y && box.max.y <= this.max.y && 13254 this.min.z <= box.min.z && box.max.z <= this.max.z; 13255 13256 }, 13257 13258 getParameter: function ( point, target ) { 13259 13260 // This can potentially have a divide by zero if the box 13261 // has a size dimension of 0. 13262 13263 if ( target === undefined ) { 13264 13265 console.warn( 'THREE.Box3: .getParameter() target is now required' ); 13266 target = new Vector3(); 13267 13268 } 13269 13270 return target.set( 13271 ( point.x - this.min.x ) / ( this.max.x - this.min.x ), 13272 ( point.y - this.min.y ) / ( this.max.y - this.min.y ), 13273 ( point.z - this.min.z ) / ( this.max.z - this.min.z ) 13274 ); 13275 13276 }, 13277 13278 intersectsBox: function ( box ) { 13279 13280 // using 6 splitting planes to rule out intersections. 13281 return box.max.x < this.min.x || box.min.x > this.max.x || 13282 box.max.y < this.min.y || box.min.y > this.max.y || 13283 box.max.z < this.min.z || box.min.z > this.max.z ? false : true; 13284 13285 }, 13286 13287 intersectsSphere: ( function () { 13288 13289 var closestPoint = new Vector3(); 13290 13291 return function intersectsSphere( sphere ) { 13292 13293 // Find the point on the AABB closest to the sphere center. 13294 this.clampPoint( sphere.center, closestPoint ); 13295 13296 // If that point is inside the sphere, the AABB and sphere intersect. 13297 return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); 13298 13299 }; 13300 13301 } )(), 13302 13303 intersectsPlane: function ( plane ) { 13304 13305 // We compute the minimum and maximum dot product values. If those values 13306 // are on the same side (back or front) of the plane, then there is no intersection. 13307 13308 var min, max; 13309 13310 if ( plane.normal.x > 0 ) { 13311 13312 min = plane.normal.x * this.min.x; 13313 max = plane.normal.x * this.max.x; 13314 13315 } else { 13316 13317 min = plane.normal.x * this.max.x; 13318 max = plane.normal.x * this.min.x; 13319 13320 } 13321 13322 if ( plane.normal.y > 0 ) { 13323 13324 min += plane.normal.y * this.min.y; 13325 max += plane.normal.y * this.max.y; 13326 13327 } else { 13328 13329 min += plane.normal.y * this.max.y; 13330 max += plane.normal.y * this.min.y; 13331 13332 } 13333 13334 if ( plane.normal.z > 0 ) { 13335 13336 min += plane.normal.z * this.min.z; 13337 max += plane.normal.z * this.max.z; 13338 13339 } else { 13340 13341 min += plane.normal.z * this.max.z; 13342 max += plane.normal.z * this.min.z; 13343 13344 } 13345 13346 return ( min <= plane.constant && max >= plane.constant ); 13347 13348 }, 13349 13350 intersectsTriangle: ( function () { 13351 13352 // triangle centered vertices 13353 var v0 = new Vector3(); 13354 var v1 = new Vector3(); 13355 var v2 = new Vector3(); 13356 13357 // triangle edge vectors 13358 var f0 = new Vector3(); 13359 var f1 = new Vector3(); 13360 var f2 = new Vector3(); 13361 13362 var testAxis = new Vector3(); 13363 13364 var center = new Vector3(); 13365 var extents = new Vector3(); 13366 13367 var triangleNormal = new Vector3(); 13368 13369 function satForAxes( axes ) { 13370 13371 var i, j; 13372 13373 for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { 13374 13375 testAxis.fromArray( axes, i ); 13376 // project the aabb onto the seperating axis 13377 var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); 13378 // project all 3 vertices of the triangle onto the seperating axis 13379 var p0 = v0.dot( testAxis ); 13380 var p1 = v1.dot( testAxis ); 13381 var p2 = v2.dot( testAxis ); 13382 // actual test, basically see if either of the most extreme of the triangle points intersects r 13383 if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { 13384 13385 // points of the projected triangle are outside the projected half-length of the aabb 13386 // the axis is seperating and we can exit 13387 return false; 13388 13389 } 13390 13391 } 13392 13393 return true; 13394 13395 } 13396 13397 return function intersectsTriangle( triangle ) { 13398 13399 if ( this.isEmpty() ) { 13400 13401 return false; 13402 13403 } 13404 13405 // compute box center and extents 13406 this.getCenter( center ); 13407 extents.subVectors( this.max, center ); 13408 13409 // translate triangle to aabb origin 13410 v0.subVectors( triangle.a, center ); 13411 v1.subVectors( triangle.b, center ); 13412 v2.subVectors( triangle.c, center ); 13413 13414 // compute edge vectors for triangle 13415 f0.subVectors( v1, v0 ); 13416 f1.subVectors( v2, v1 ); 13417 f2.subVectors( v0, v2 ); 13418 13419 // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb 13420 // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation 13421 // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) 13422 var axes = [ 13423 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, 13424 f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, 13425 - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 13426 ]; 13427 if ( ! satForAxes( axes ) ) { 13428 13429 return false;
13430 13431 } 13432 13433 // test 3 face normals from the aabb 13434 axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; 13435 if ( ! satForAxes( axes ) ) { 13436 13437 return false; 13438 13439 } 13440 13441 // finally testing the face normal of the triangle 13442 // use already existing triangle edge vectors here 13443 triangleNormal.crossVectors( f0, f1 ); 13444 axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; 13445 return satForAxes( axes ); 13446 13447 }; 13448 13449 } )(), 13450 13451 clampPoint: function ( point, target ) { 13452 13453 if ( target === undefined ) { 13454 13455 console.warn( 'THREE.Box3: .clampPoint() target is now required' ); 13456 target = new Vector3(); 13457 13458 } 13459 13460 return target.copy( point ).clamp( this.min, this.max ); 13461 13462 }, 13463 13464 distanceToPoint: function () { 13465 13466 var v1 = new Vector3(); 13467 13468 return function distanceToPoint( point ) { 13469 13470 var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); 13471 return clampedPoint.sub( point ).length(); 13472 13473 }; 13474 13475 }(), 13476 13477 getBoundingSphere: function () { 13478 13479 var v1 = new Vector3(); 13480 13481 return function getBoundingSphere( target ) { 13482 13483 if ( target === undefined ) { 13484 13485 console.warn( 'THREE.Box3: .getBoundingSphere() target is now required' ); 13486 target = new Sphere(); 13487 13488 } 13489 13490 this.getCenter( target.center ); 13491 13492 target.radius = this.getSize( v1 ).length() * 0.5; 13493 13494 return target; 13495 13496 }; 13497 13498 }(), 13499 13500 intersect: function ( box ) { 13501 13502 this.min.max( box.min ); 13503 this.max.min( box.max ); 13504 13505 // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. 13506 if ( this.isEmpty() ) this.makeEmpty(); 13507 13508 return this; 13509 13510 }, 13511 13512 union: function ( box ) { 13513 13514 this.min.min( box.min ); 13515 this.max.max( box.max ); 13516 13517 return this; 13518 13519 }, 13520 13521 applyMatrix4: function ( matrix ) { 13522 13523 // transform of empty box is an empty box. 13524 if ( this.isEmpty( ) ) return this; 13525 13526 var m = matrix.elements; 13527 13528 var xax = m[ 0 ] * this.min.x, xay = m[ 1 ] * this.min.x, xaz = m[ 2 ] * this.min.x; 13529 var xbx = m[ 0 ] * this.max.x, xby = m[ 1 ] * this.max.x, xbz = m[ 2 ] * this.max.x; 13530 var yax = m[ 4 ] * this.min.y, yay = m[ 5 ] * this.min.y, yaz = m[ 6 ] * this.min.y; 13531 var ybx = m[ 4 ] * this.max.y, yby = m[ 5 ] * this.max.y, ybz = m[ 6 ] * this.max.y; 13532 var zax = m[ 8 ] * this.min.z, zay = m[ 9 ] * this.min.z, zaz = m[ 10 ] * this.min.z; 13533 var zbx = m[ 8 ] * this.max.z, zby = m[ 9 ] * this.max.z, zbz = m[ 10 ] * this.max.z; 13534 13535 this.min.x = Math.min( xax, xbx ) + Math.min( yax, ybx ) + Math.min( zax, zbx ) + m[ 12 ]; 13536 this.min.y = Math.min( xay, xby ) + Math.min( yay, yby ) + Math.min( zay, zby ) + m[ 13 ]; 13537 this.min.z = Math.min( xaz, xbz ) + Math.min( yaz, ybz ) + Math.min( zaz, zbz ) + m[ 14 ]; 13538 this.max.x = Math.max( xax, xbx ) + Math.max( yax, ybx ) + Math.max( zax, zbx ) + m[ 12 ]; 13539 this.max.y = Math.max( xay, xby ) + Math.max( yay, yby ) + Math.max( zay, zby ) + m[ 13 ]; 13540 this.max.z = Math.max( xaz, xbz ) + Math.max( yaz, ybz ) + Math.max( zaz, zbz ) + m[ 14 ]; 13541 13542 return this; 13543 13544 }, 13545 13546 translate: function ( offset ) { 13547 13548 this.min.add( offset ); 13549 this.max.add( offset ); 13550 13551 return this; 13552 13553 }, 13554 13555 equals: function ( box ) { 13556 13557 return box.min.equals( this.min ) && box.max.equals( this.max ); 13558 13559 } 13560 13561 } ); 13562 13563 /** 13564 * @author bhouston / http://clara.io 13565 * @author mrdoob / http://mrdoob.com/ 13566 */ 13567 13568 function Sphere( center, radius ) { 13569 13570 this.center = ( center !== undefined ) ? center : new Vector3(); 13571 this.radius = ( radius !== undefined ) ? radius : 0; 13572 13573 } 13574 13575 Object.assign( Sphere.prototype, { 13576
vendor: 7,519 bytes, lines 13577-13969
13577 set: function ( center, radius ) { 13578 13579 this.center.copy( center ); 13580 this.radius = radius; 13581 13582 return this; 13583 13584 }, 13585 13586 setFromPoints: function () { 13587 13588 var box = new Box3(); 13589 13590 return function setFromPoints( points, optionalCenter ) { 13591 13592 var center = this.center; 13593 13594 if ( optionalCenter !== undefined ) { 13595 13596 center.copy( optionalCenter ); 13597 13598 } else { 13599 13600 box.setFromPoints( points ).getCenter( center ); 13601 13602 } 13603 13604 var maxRadiusSq = 0; 13605 13606 for ( var i = 0, il = points.length; i < il; i ++ ) { 13607 13608 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); 13609 13610 } 13611 13612 this.radius = Math.sqrt( maxRadiusSq ); 13613 13614 return this; 13615 13616 }; 13617 13618 }(), 13619 13620 clone: function () { 13621 13622 return new this.constructor().copy( this ); 13623 13624 }, 13625 13626 copy: function ( sphere ) { 13627 13628 this.center.copy( sphere.center ); 13629 this.radius = sphere.radius; 13630 13631 return this; 13632 13633 }, 13634 13635 empty: function () { 13636 13637 return ( this.radius <= 0 ); 13638 13639 }, 13640 13641 containsPoint: function ( point ) { 13642 13643 return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); 13644 13645 }, 13646 13647 distanceToPoint: function ( point ) { 13648 13649 return ( point.distanceTo( this.center ) - this.radius ); 13650 13651 }, 13652 13653 intersectsSphere: function ( sphere ) { 13654 13655 var radiusSum = this.radius + sphere.radius; 13656 13657 return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); 13658 13659 }, 13660 13661 intersectsBox: function ( box ) { 13662 13663 return box.intersectsSphere( this ); 13664 13665 }, 13666 13667 intersectsPlane: function ( plane ) { 13668 13669 return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; 13670 13671 }, 13672 13673 clampPoint: function ( point, target ) { 13674 13675 var deltaLengthSq = this.center.distanceToSquared( point ); 13676 13677 if ( target === undefined ) { 13678 13679 console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); 13680 target = new Vector3(); 13681 13682 } 13683 13684 target.copy( point ); 13685 13686 if ( deltaLengthSq > ( this.radius * this.radius ) ) { 13687 13688 target.sub( this.center ).normalize(); 13689 target.multiplyScalar( this.radius ).add( this.center ); 13690 13691 } 13692 13693 return target; 13694 13695 }, 13696 13697 getBoundingBox: function ( target ) { 13698 13699 if ( target === undefined ) { 13700 13701 console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); 13702 target = new Box3(); 13703 13704 } 13705 13706 target.set( this.center, this.center ); 13707 target.expandByScalar( this.radius ); 13708 13709 return target; 13710 13711 }, 13712 13713 applyMatrix4: function ( matrix ) { 13714 13715 this.center.applyMatrix4( matrix ); 13716 this.radius = this.radius * matrix.getMaxScaleOnAxis(); 13717 13718 return this; 13719 13720 }, 13721 13722 translate: function ( offset ) { 13723 13724 this.center.add( offset ); 13725 13726 return this; 13727 13728 }, 13729 13730 equals: function ( sphere ) { 13731 13732 return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); 13733 13734 } 13735 13736 } ); 13737 13738 /** 13739 * @author bhouston / http://clara.io 13740 */ 13741 13742 function Plane( normal, constant ) { 13743 13744 // normal is assumed to be normalized 13745 13746 this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); 13747 this.constant = ( constant !== undefined ) ? constant : 0; 13748 13749 } 13750 13751 Object.assign( Plane.prototype, { 13752 13753 set: function ( normal, constant ) { 13754 13755 this.normal.copy( normal ); 13756 this.constant = constant; 13757 13758 return this; 13759 13760 }, 13761 13762 setComponents: function ( x, y, z, w ) { 13763 13764 this.normal.set( x, y, z ); 13765 this.constant = w; 13766 13767 return this; 13768 13769 }, 13770 13771 setFromNormalAndCoplanarPoint: function ( normal, point ) { 13772 13773 this.normal.copy( normal ); 13774 this.constant = - point.dot( this.normal ); 13775 13776 return this; 13777 13778 }, 13779 13780 setFromCoplanarPoints: function () { 13781 13782 var v1 = new Vector3(); 13783 var v2 = new Vector3(); 13784 13785 return function setFromCoplanarPoints( a, b, c ) { 13786 13787 var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); 13788 13789 // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? 13790 13791 this.setFromNormalAndCoplanarPoint( normal, a ); 13792 13793 return this; 13794 13795 }; 13796 13797 }(), 13798 13799 clone: function () { 13800 13801 return new this.constructor().copy( this ); 13802 13803 }, 13804 13805 copy: function ( plane ) { 13806 13807 this.normal.copy( plane.normal ); 13808 this.constant = plane.constant; 13809 13810 return this; 13811 13812 }, 13813 13814 normalize: function () { 13815 13816 // Note: will lead to a divide by zero if the plane is invalid. 13817 13818 var inverseNormalLength = 1.0 / this.normal.length(); 13819 this.normal.multiplyScalar( inverseNormalLength ); 13820 this.constant *= inverseNormalLength; 13821 13822 return this; 13823 13824 }, 13825 13826 negate: function () { 13827 13828 this.constant *= - 1; 13829 this.normal.negate(); 13830 13831 return this; 13832 13833 }, 13834 13835 distanceToPoint: function ( point ) { 13836 13837 return this.normal.dot( point ) + this.constant; 13838 13839 }, 13840 13841 distanceToSphere: function ( sphere ) { 13842 13843 return this.distanceToPoint( sphere.center ) - sphere.radius; 13844 13845 }, 13846 13847 projectPoint: function ( point, target ) { 13848 13849 if ( target === undefined ) { 13850 13851 console.warn( 'THREE.Plane: .projectPoint() target is now required' ); 13852 target = new Vector3(); 13853 13854 } 13855 13856 return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); 13857 13858 }, 13859 13860 intersectLine: function () { 13861 13862 var v1 = new Vector3(); 13863 13864 return function intersectLine( line, target ) { 13865 13866 if ( target === undefined ) { 13867 13868 console.warn( 'THREE.Plane: .intersectLine() target is now required' ); 13869 target = new Vector3(); 13870 13871 } 13872 13873 var direction = line.delta( v1 ); 13874 13875 var denominator = this.normal.dot( direction ); 13876 13877 if ( denominator === 0 ) { 13878 13879 // line is coplanar, return origin 13880 if ( this.distanceToPoint( line.start ) === 0 ) { 13881 13882 return target.copy( line.start ); 13883 13884 } 13885 13886 // Unsure if this is the correct method to handle this case. 13887 return undefined; 13888 13889 } 13890 13891 var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; 13892 13893 if ( t < 0 || t > 1 ) { 13894 13895 return undefined; 13896 13897 } 13898 13899 return target.copy( direction ).multiplyScalar( t ).add( line.start ); 13900 13901 }; 13902 13903 }(), 13904 13905 intersectsLine: function ( line ) { 13906 13907 // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. 13908 13909 var startSign = this.distanceToPoint( line.start ); 13910 var endSign = this.distanceToPoint( line.end ); 13911 13912 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); 13913 13914 }, 13915 13916 intersectsBox: function ( box ) { 13917 13918 return box.intersectsPlane( this ); 13919 13920 }, 13921 13922 intersectsSphere: function ( sphere ) { 13923 13924 return sphere.intersectsPlane( this ); 13925 13926 }, 13927 13928 coplanarPoint: function ( target ) { 13929 13930 if ( target === undefined ) { 13931 13932 console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); 13933 target = new Vector3(); 13934 13935 } 13936 13937 return target.copy( this.normal ).multiplyScalar( - this.constant ); 13938 13939 }, 13940 13941 applyMatrix4: function () { 13942 13943 var v1 = new Vector3(); 13944 var m1 = new Matrix3(); 13945 13946 return function applyMatrix4( matrix, optionalNormalMatrix ) { 13947 13948 var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); 13949 13950 var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); 13951 13952 var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); 13953 13954 this.constant = - referencePoint.dot( normal ); 13955 13956 return this; 13957 13958 }; 13959 13960 }(), 13961 13962 translate: function ( offset ) { 13963 13964 this.constant -= offset.dot( this.normal ); 13965 13966 return this; 13967 13968 }, 13969
vendor: 4,243 bytes, lines 13970-14161
13970 equals: function ( plane ) { 13971 13972 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); 13973 13974 } 13975 13976 } ); 13977 13978 /** 13979 * @author mrdoob / http://mrdoob.com/ 13980 * @author alteredq / http://alteredqualia.com/ 13981 * @author bhouston / http://clara.io 13982 */ 13983 13984 function Frustum( p0, p1, p2, p3, p4, p5 ) { 13985 13986 this.planes = [ 13987 13988 ( p0 !== undefined ) ? p0 : new Plane(), 13989 ( p1 !== undefined ) ? p1 : new Plane(), 13990 ( p2 !== undefined ) ? p2 : new Plane(), 13991 ( p3 !== undefined ) ? p3 : new Plane(), 13992 ( p4 !== undefined ) ? p4 : new Plane(), 13993 ( p5 !== undefined ) ? p5 : new Plane() 13994 13995 ]; 13996 13997 } 13998 13999 Object.assign( Frustum.prototype, { 14000 14001 set: function ( p0, p1, p2, p3, p4, p5 ) { 14002 14003 var planes = this.planes; 14004 14005 planes[ 0 ].copy( p0 ); 14006 planes[ 1 ].copy( p1 ); 14007 planes[ 2 ].copy( p2 ); 14008 planes[ 3 ].copy( p3 ); 14009 planes[ 4 ].copy( p4 ); 14010 planes[ 5 ].copy( p5 ); 14011 14012 return this; 14013 14014 }, 14015 14016 clone: function () { 14017 14018 return new this.constructor().copy( this ); 14019 14020 }, 14021 14022 copy: function ( frustum ) { 14023 14024 var planes = this.planes; 14025 14026 for ( var i = 0; i < 6; i ++ ) { 14027 14028 planes[ i ].copy( frustum.planes[ i ] ); 14029 14030 } 14031 14032 return this; 14033 14034 }, 14035 14036 setFromMatrix: function ( m ) { 14037 14038 var planes = this.planes; 14039 var me = m.elements; 14040 var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; 14041 var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; 14042 var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; 14043 var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; 14044 14045 planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); 14046 planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); 14047 planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); 14048 planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); 14049 planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); 14050 planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); 14051 14052 return this; 14053 14054 }, 14055 14056 intersectsObject: function () { 14057 14058 var sphere = new Sphere(); 14059 14060 return function intersectsObject( object ) { 14061 14062 var geometry = object.geometry; 14063 14064 if ( geometry.boundingSphere === null ) 14065 geometry.computeBoundingSphere(); 14066 14067 sphere.copy( geometry.boundingSphere ) 14068 .applyMatrix4( object.matrixWorld ); 14069 14070 return this.intersectsSphere( sphere ); 14071 14072 }; 14073 14074 }(), 14075 14076 intersectsSprite: function () { 14077 14078 var sphere = new Sphere(); 14079 14080 return function intersectsSprite( sprite ) { 14081 14082 sphere.center.set( 0, 0, 0 ); 14083 sphere.radius = 0.7071067811865476; 14084 sphere.applyMatrix4( sprite.matrixWorld ); 14085 14086 return this.intersectsSphere( sphere ); 14087 14088 }; 14089 14090 }(), 14091 14092 intersectsSphere: function ( sphere ) { 14093 14094 var planes = this.planes; 14095 var center = sphere.center; 14096 var negRadius = - sphere.radius; 14097 14098 for ( var i = 0; i < 6; i ++ ) { 14099 14100 var distance = planes[ i ].distanceToPoint( center ); 14101 14102 if ( distance < negRadius ) { 14103 14104 return false; 14105 14106 } 14107 14108 } 14109 14110 return true; 14111 14112 }, 14113 14114 intersectsBox: function () { 14115 14116 var p1 = new Vector3(), 14117 p2 = new Vector3(); 14118 14119 return function intersectsBox( box ) { 14120 14121 var planes = this.planes; 14122 14123 for ( var i = 0; i < 6; i ++ ) { 14124 14125 var plane = planes[ i ]; 14126 14127 p1.x = plane.normal.x > 0 ? box.min.x : box.max.x; 14128 p2.x = plane.normal.x > 0 ? box.max.x : box.min.x; 14129 p1.y = plane.normal.y > 0 ? box.min.y : box.max.y; 14130 p2.y = plane.normal.y > 0 ? box.max.y : box.min.y; 14131 p1.z = plane.normal.z > 0 ? box.min.z : box.max.z; 14132 p2.z = plane.normal.z > 0 ? box.max.z : box.min.z; 14133 14134 var d1 = plane.distanceToPoint( p1 ); 14135 var d2 = plane.distanceToPoint( p2 ); 14136 14137 // if both outside plane, no intersection 14138 14139 if ( d1 < 0 && d2 < 0 ) { 14140 14141 return false; 14142 14143 } 14144 14145 } 14146 14147 return true; 14148 14149 }; 14150 14151 }(), 14152 14153 containsPoint: function ( point ) { 14154 14155 var planes = this.planes; 14156 14157 for ( var i = 0; i < 6; i ++ ) { 14158 14159 if ( planes[ i ].distanceToPoint( point ) < 0 ) { 14160 14161 return false;
14162 14163 } 14164 14165 } 14166 14167 return true; 14168 14169 } 14170 14171 } ); 14172 14173 var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n"; 14174 14175 var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n"; 14176 14177 var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n"; 14178 14179 var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n"; 14180 14181 var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; 14182 14183 var begin_vertex = "\nvec3 transformed = vec3( position );\n"; 14184 14185 var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n"; 14186 14187 var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;
14187\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );
14187\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n"; 14188 14189 var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}
14189\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n"; 14190 14191 var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif\n"; 14192 14193 var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n"; 14194 14195 var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n"; 14196 14197 var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n"; 14198 14199 var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; 14200 14201 var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n"; 14202 14203 var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; 14204 14205 var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; 14206 14207 var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\n"; 14208 14209 var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);
14209\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n"; 14210 14211 var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n"; 14212 14213 var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n"; 14214 14215 var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n"; 14216 14217 var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n"; 14218 14219 var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n"; 14220 14221 var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n"; 14222 14223 var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}
14223\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n"; 14224 14225 var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n"; 14226 14227 var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n"; 14228 14229 var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n"; 14230 14231 var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;
14231\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n"; 14232 14233 var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif"; 14234 14235 var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n"; 14236 14237 var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n"; 14238 14239 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n"; 14240 14241 var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n"; 14242 14243 var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n"; 14244 14245 var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; 14246 14247 var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n"; 14248 14249 var lights_pars_begin = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}
14249\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n"; 14250 14251 var lights_pars_maps = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShinine
14251ssExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n"; 14252 14253 var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n"; 14254 14255 var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n"; 14256 14257 var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n"; 14258 14259 var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;
14259\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n"; 14260 14261 var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}
14261\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif\n"; 14262 14263 var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif\n"; 14264 14265 var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n"; 14266 14267 var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; 14268 14269 var logdepthbuf_pars_fragment = "#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n"; 14270 14271 var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif"; 14272 14273 var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif\n"; 14274 14275 var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n"; 14276 14277 var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n"; 14278 14279 var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n"; 14280 14281 var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif\n"; 14282 14283 var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n"; 14284 14285 var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; 14286 14287 var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n"; 14288 14289 var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; 14290 14291 var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n"; 14292 14293 var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n#endif\n"; 14294 14295 var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\tnormal = perturbN
14295ormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n"; 14296 14297 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n"; 14298 14299 var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n"; 14300 14301 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n"; 14302 14303 var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n"; 14304 14305 var dithering_fragment = "#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n"; 14306 14307 var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n"; 14308 14309 var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n"; 14310 14311 var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; 14312 14313 var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );
14313\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n"; 14314 14315 var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n"; 14316 14317 var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n"; 14318 14319 var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n"; 14320 14321 var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; 14322 14323 var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n"; 14324 14325 var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n"; 14326 14327 var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;
14327\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n"; 14328 14329 var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; 14330 14331 var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; 14332 14333 var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n"; 14334 14335 var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n"; 14336 14337 var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; 14338 14339 var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\n"; 14340 14341 var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; 14342 14343 var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; 14344 14345 var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; 14346 14347 var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; 14348 14349 var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n"; 14350 14351 var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n"; 14352 14353 var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}\n"; 14354 14355 var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; 14356 14357 var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n"; 14358 14359 var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}\n"; 14360 14361 var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}\n"; 14362 14363 var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n"; 14364 14365 var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n"; 14366 14367 var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n"; 14368 14369 var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n"; 14370 14371 var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n"; 14372 14373 var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n"; 14374 14375 var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_pars_maps>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n"; 14376 14377 var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_pars_maps>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n"; 14378 14379 var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_pars_maps>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n"; 14380 14381 var meshphong_vert = "#define PHONG\nvarying vec3 vView
14381Position;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n"; 14382 14383 var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_pars_maps>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n"; 14384 14385 var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n"; 14386 14387 var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n"; 14388 14389 var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n"; 14390 14391 var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n"; 14392 14393 var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}\n"; 14394 14395 var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <fog_fragment>\n}\n"; 14396 14397 var shadow_vert = "#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n"; 14398 14399 var ShaderChunk = { 14400 alphamap_fragment: alphamap_fragment, 14401 alphamap_pars_fragment: alphamap_pars_fragment, 14402 alphatest_fragment: alphatest_fragment, 14403 aomap_fragment: aomap_fragment, 14404 aomap_pars_fragment: aomap_pars_fragment, 14405 begin_vertex: begin_vertex, 14406 beginnormal_vertex: beginnormal_vertex, 14407 bsdfs: bsdfs, 14408 bumpmap_pars_fragment: bumpmap_pars_fragment, 14409 clipping_planes_fragment: clipping_planes_fragment, 14410 clipping_planes_pars_fragment: clipping_planes_pars_fragment, 14411 clipping_planes_pars_vertex: clipping_planes_pars_vertex, 14412 clipping_planes_vertex: clipping_planes_vertex, 14413 color_fragment: color_fragment, 14414 color_pars_fragment: color_pars_fragment, 14415 color_pars_vertex: color_pars_vertex, 14416 color_vertex: color_vertex, 14417 common: common, 14418 cube_uv_reflection_fragment: cube_uv_reflection_fragment, 14419 defaultnormal_vertex: defaultnormal_vertex, 14420 displacementmap_pars_vertex: displacementmap_pars_vertex, 14421 displacementmap_vertex: displacementmap_vertex, 14422 emissivemap_fragment: emissivemap_fragment, 14423 emissivemap_pars_fragment: emissivemap_pars_fragment, 14424 encodings_fragment: encodings_fragment, 14425 encodings_pars_fragment: encodings_pars_fragment, 14426 envmap_fragment: envmap_fragment, 14427 envmap_pars_fragment: envmap_pars_fragment, 14428 envmap_pars_vertex: envmap_pars_vertex, 14429 envmap_vertex: envmap_vertex, 14430 fog_vertex: fog_vertex, 14431 fog_pars_vertex: fog_pars_vertex, 14432 fog_fragment: fog_fragment, 14433 fog_pars_fragment: fog_pars_fragment, 14434 gradientmap_pars_fragment: gradientmap_pars_fragment, 14435 lightmap_fragment: lightmap_fragment, 14436 lightmap_pars_fragment: lightmap_pars_fragment, 14437 lights_lambert_vertex: lights_lambert_vertex, 14438 lights_pars_begin: lights_pars_begin, 14439 lights_pars_maps: lights_pars_maps, 14440 lights_phong_fragment: lights_phong_fragment, 14441 lights_phong_pars_fragment: lights_phong_pars_fragment, 14442 lights_physical_fragment: lights_physical_fragment, 14443 lights_physical_pars_fragment: lights_physical_pars_fragment, 14444 lights_fragment_begin: lights_fragment_begin, 14445 lights_fragment_maps: lights_fragment_maps, 14446 lights_fragment_end: lights_fragment_end, 14447 logdepthbuf_fragment: logdepthbuf_fragment, 14448 logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, 14449 logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, 14450 logdepthbuf_vertex: logdepthbuf_vertex, 14451 map_fragment: map_fragment, 14452 map_pars_fragment: map_pars_fragment, 14453 map_particle_fragment: map_particle_fragment, 14454 map_particle_pars_fragment: map_particle_pars_fragment, 14455 metalnessmap_fragment: metalnessmap_fragment, 14456 metalnessmap_pars_fragment: metalnessmap_pars_fragment, 14457 morphnormal_vertex: morphnormal_vertex, 14458 morphtarget_pars_vertex: morphtarget_pars_vertex, 14459 morphtarget_vertex: morphtarget_vertex, 14460 normal_fragment_begin: normal_fragment_begin, 14461 normal_fragment_maps: normal_fragment_maps, 14462 normalmap_pars_fragment: normalmap_pars_fragment, 14463 packing: packing, 14464 premultiplied_alpha_fragment: premultiplied_alpha_fragment, 14465 project_vertex: project_vertex, 14466 dithering_fragment: dithering_fragment, 14467 dithering_pars_fragment: dithering_pars_fragment, 14468 roughnessmap_fragment: roughnessmap_fragment, 14469 roughnessmap_pars_fragment: roughnessmap_pars_fragment, 14470 shadowmap_pars_fragment: shadowmap_pars_fragment, 14471 shadowmap_pars_vertex: shadowmap_pars_vertex, 14472 shadowmap_vertex: shadowmap_vertex, 14473 shadowmask_pars_fragment: shadowmask_pars_fragment, 14474 skinbase_vertex: skinbase_vertex, 14475 skinning_pars_vertex: skinning_pars_vertex, 14476 skinning_vertex: skinning_vertex, 14477 skinnormal_vertex: skinnormal_vertex, 14478 specularmap_fragment: specularmap_fragment, 14479 specularmap_pars_fragment: specularmap_pars_fragment, 14480 tonemapping_fragment: tonemapping_fragment, 14481 tonemapping_pars_fragment: tonemapping_pars_fragment, 14482 uv_pars_fragment: uv_pars_fragment, 14483 uv_pars_vertex: uv_pars_vertex, 14484 uv_vertex: uv_vertex, 14485 uv2_pars_fragment: uv2_pars_fragment, 14486 uv2_pars_vertex: uv2_pars_vertex, 14487 uv2_vertex: uv2_vertex, 14488 worldpos_vertex: worldpos_vertex, 14489 14490 cube_frag: cube_frag, 14491 cube_vert: cube_vert, 14492 depth_frag: depth_frag, 14493 depth_vert: depth_vert, 14494 distanceRGBA_frag: distanceRGBA_frag, 14495 distanceRGBA_vert: distanceRGBA_vert, 14496 equirect_frag: equirect_frag, 14497 equirect_vert: equirect_vert, 14498 linedashed_frag: linedashed_frag, 14499 linedashed_vert: linedashed_vert, 14500 meshbasic_frag: meshbasic_frag, 14501 meshbasic_vert: meshbasic_vert, 14502 meshlambert_frag: meshlambert_frag, 14503 meshlambert_vert: meshlambert_vert, 14504 meshphong_frag: meshphong_frag, 14505 meshphong_vert: meshphong_vert, 14506 meshphysical_frag: meshphysical_frag, 14507 meshphysical_vert: meshphysical_vert, 14508 normal_frag: normal_frag, 14509 normal_vert: normal_vert, 14510 points_frag: points_frag, 14511 points_vert: points_vert, 14512 shadow_frag: shadow_frag, 14513 shadow_vert: shadow_vert 14514 }; 14515 14516 /** 14517 * Uniform Utilities 14518 */ 14519 14520 var UniformsUtils = { 14521 14522 merge: function ( uniforms ) { 14523 14524 var merged = {}; 14525 14526 for ( var u = 0; u < uniforms.length; u ++ ) { 14527 14528 var tmp = this.clone( uniforms[ u ] ); 14529 14530 for ( var p in tmp ) { 14531 14532 merged[ p ] = tmp[ p ]; 14533 14534 } 14535 14536 } 14537 14538 return merged; 14539 14540 }, 14541
14542 clone: function ( uniforms_src ) { 14543 14544 var uniforms_dst = {}; 14545 14546 for ( var u in uniforms_src ) { 14547 14548 uniforms_dst[ u ] = {}; 14549 14550 for ( var p in uniforms_src[ u ] ) { 14551 14552 var parameter_src = uniforms_src[ u ][ p ]; 14553 14554 if ( parameter_src && ( parameter_src.isColor || 14555 parameter_src.isMatrix3 || parameter_src.isMatrix4 || 14556 parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 || 14557 parameter_src.isTexture ) ) { 14558 14559 uniforms_dst[ u ][ p ] = parameter_src.clone(); 14560 14561 } else if ( Array.isArray( parameter_src ) ) { 14562 14563 uniforms_dst[ u ][ p ] = parameter_src.slice(); 14564 14565 } else { 14566 14567 uniforms_dst[ u ][ p ] = parameter_src; 14568 14569 } 14570 14571 } 14572 14573 } 14574 14575 return uniforms_dst; 14576 14577 } 14578 14579 }; 14580 14581 /** 14582 * @author mrdoob / http://mrdoob.com/ 14583 */ 14584 14585 var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 14586 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, 14587 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, 14588 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, 14589 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, 14590 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, 14591 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, 14592 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, 14593 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, 14594 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, 14595 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, 14596 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, 14597 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, 14598 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, 14599 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, 14600 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, 14601 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, 14602 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, 14603 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, 14604 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, 14605 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, 14606 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, 14607 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, 14608 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; 14609 14610 function Color( r, g, b ) { 14611 14612 if ( g === undefined && b === undefined ) { 14613 14614 // r is THREE.Color, hex or string 14615 return this.set( r ); 14616 14617 } 14618 14619 return this.setRGB( r, g, b ); 14620 14621 } 14622 14623 Object.assign( Color.prototype, { 14624
vendor: 12,238 bytes, lines 14625-15307
14625 isColor: true, 14626 14627 r: 1, g: 1, b: 1, 14628 14629 set: function ( value ) { 14630 14631 if ( value && value.isColor ) { 14632 14633 this.copy( value ); 14634 14635 } else if ( typeof value === 'number' ) { 14636 14637 this.setHex( value ); 14638 14639 } else if ( typeof value === 'string' ) { 14640 14641 this.setStyle( value ); 14642 14643 } 14644 14645 return this; 14646 14647 }, 14648 14649 setScalar: function ( scalar ) { 14650 14651 this.r = scalar; 14652 this.g = scalar; 14653 this.b = scalar; 14654 14655 return this; 14656 14657 }, 14658 14659 setHex: function ( hex ) { 14660 14661 hex = Math.floor( hex ); 14662 14663 this.r = ( hex >> 16 & 255 ) / 255; 14664 this.g = ( hex >> 8 & 255 ) / 255; 14665 this.b = ( hex & 255 ) / 255; 14666 14667 return this; 14668 14669 }, 14670 14671 setRGB: function ( r, g, b ) { 14672 14673 this.r = r; 14674 this.g = g; 14675 this.b = b; 14676 14677 return this; 14678 14679 }, 14680 14681 setHSL: function () { 14682 14683 function hue2rgb( p, q, t ) { 14684 14685 if ( t < 0 ) t += 1; 14686 if ( t > 1 ) t -= 1; 14687 if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; 14688 if ( t < 1 / 2 ) return q; 14689 if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); 14690 return p; 14691 14692 } 14693 14694 return function setHSL( h, s, l ) { 14695 14696 // h,s,l ranges are in 0.0 - 1.0 14697 h = _Math.euclideanModulo( h, 1 ); 14698 s = _Math.clamp( s, 0, 1 ); 14699 l = _Math.clamp( l, 0, 1 ); 14700 14701 if ( s === 0 ) { 14702 14703 this.r = this.g = this.b = l; 14704 14705 } else { 14706 14707 var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); 14708 var q = ( 2 * l ) - p; 14709 14710 this.r = hue2rgb( q, p, h + 1 / 3 ); 14711 this.g = hue2rgb( q, p, h ); 14712 this.b = hue2rgb( q, p, h - 1 / 3 ); 14713 14714 } 14715 14716 return this; 14717 14718 }; 14719 14720 }(), 14721 14722 setStyle: function ( style ) { 14723 14724 function handleAlpha( string ) { 14725 14726 if ( string === undefined ) return; 14727 14728 if ( parseFloat( string ) < 1 ) { 14729 14730 console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); 14731 14732 } 14733 14734 } 14735 14736 14737 var m; 14738 14739 if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { 14740 14741 // rgb / hsl 14742 14743 var color; 14744 var name = m[ 1 ]; 14745 var components = m[ 2 ]; 14746 14747 switch ( name ) { 14748 14749 case 'rgb': 14750 case 'rgba': 14751 14752 if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 14753 14754 // rgb(255,0,0) rgba(255,0,0,0.5) 14755 this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; 14756 this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; 14757 this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; 14758 14759 handleAlpha( color[ 5 ] ); 14760 14761 return this; 14762 14763 } 14764 14765 if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 14766 14767 // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) 14768 this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; 14769 this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; 14770 this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; 14771 14772 handleAlpha( color[ 5 ] ); 14773 14774 return this; 14775 14776 } 14777 14778 break; 14779 14780 case 'hsl': 14781 case 'hsla': 14782 14783 if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { 14784 14785 // hsl(120,50%,50%) hsla(120,50%,50%,0.5) 14786 var h = parseFloat( color[ 1 ] ) / 360; 14787 var s = parseInt( color[ 2 ], 10 ) / 100; 14788 var l = parseInt( color[ 3 ], 10 ) / 100; 14789 14790 handleAlpha( color[ 5 ] ); 14791 14792 return this.setHSL( h, s, l ); 14793 14794 } 14795 14796 break; 14797 14798 } 14799 14800 } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { 14801 14802 // hex color 14803 14804 var hex = m[ 1 ]; 14805 var size = hex.length; 14806 14807 if ( size === 3 ) { 14808 14809 // #ff0 14810 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; 14811 this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; 14812 this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; 14813 14814 return this; 14815 14816 } else if ( size === 6 ) { 14817 14818 // #ff0000 14819 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; 14820 this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; 14821 this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; 14822 14823 return this; 14824 14825 } 14826 14827 } 14828 14829 if ( style && style.length > 0 ) { 14830 14831 // color keywords 14832 var hex = ColorKeywords[ style ]; 14833 14834 if ( hex !== undefined ) { 14835 14836 // red 14837 this.setHex( hex ); 14838 14839 } else { 14840 14841 // unknown color 14842 console.warn( 'THREE.Color: Unknown color ' + style ); 14843 14844 } 14845 14846 } 14847 14848 return this; 14849 14850 }, 14851 14852 clone: function () { 14853 14854 return new this.constructor( this.r, this.g, this.b ); 14855 14856 }, 14857 14858 copy: function ( color ) { 14859 14860 this.r = color.r; 14861 this.g = color.g; 14862 this.b = color.b; 14863 14864 return this; 14865 14866 }, 14867 14868 copyGammaToLinear: function ( color, gammaFactor ) { 14869 14870 if ( gammaFactor === undefined ) gammaFactor = 2.0; 14871 14872 this.r = Math.pow( color.r, gammaFactor ); 14873 this.g = Math.pow( color.g, gammaFactor ); 14874 this.b = Math.pow( color.b, gammaFactor ); 14875 14876 return this; 14877 14878 }, 14879 14880 copyLinearToGamma: function ( color, gammaFactor ) { 14881 14882 if ( gammaFactor === undefined ) gammaFactor = 2.0; 14883 14884 var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; 14885 14886 this.r = Math.pow( color.r, safeInverse ); 14887 this.g = Math.pow( color.g, safeInverse ); 14888 this.b = Math.pow( color.b, safeInverse ); 14889 14890 return this; 14891 14892 }, 14893 14894 convertGammaToLinear: function ( gammaFactor ) { 14895 14896 this.copyGammaToLinear( this, gammaFactor ); 14897 14898 return this; 14899 14900 }, 14901 14902 convertLinearToGamma: function ( gammaFactor ) { 14903 14904 this.copyLinearToGamma( this, gammaFactor ); 14905 14906 return this; 14907 14908 }, 14909 14910 getHex: function () { 14911 14912 return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; 14913 14914 }, 14915 14916 getHexString: function () { 14917 14918 return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); 14919 14920 }, 14921 14922 getHSL: function ( target ) { 14923 14924 // h,s,l ranges are in 0.0 - 1.0 14925 14926 if ( target === undefined ) { 14927 14928 console.warn( 'THREE.Color: .getHSL() target is now required' ); 14929 target = { h: 0, s: 0, l: 0 }; 14930 14931 } 14932 14933 var r = this.r, g = this.g, b = this.b; 14934 14935 var max = Math.max( r, g, b ); 14936 var min = Math.min( r, g, b ); 14937 14938 var hue, saturation; 14939 var lightness = ( min + max ) / 2.0; 14940 14941 if ( min === max ) { 14942 14943 hue = 0; 14944 saturation = 0; 14945 14946 } else { 14947 14948 var delta = max - min; 14949 14950 saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); 14951 14952 switch ( max ) { 14953 14954 case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; 14955 case g: hue = ( b - r ) / delta + 2; break; 14956 case b: hue = ( r - g ) / delta + 4; break; 14957 14958 } 14959 14960 hue /= 6; 14961 14962 } 14963 14964 target.h = hue; 14965 target.s = saturation; 14966 target.l = lightness; 14967 14968 return target; 14969 14970 }, 14971 14972 getStyle: function () { 14973 14974 return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; 14975 14976 }, 14977 14978 offsetHSL: function () { 14979 14980 var hsl = {}; 14981 14982 return function ( h, s, l ) { 14983 14984 this.getHSL( hsl ); 14985 14986 hsl.h += h; hsl.s += s; hsl.l += l; 14987 14988 this.setHSL( hsl.h, hsl.s, hsl.l ); 14989 14990 return this; 14991 14992 }; 14993 14994 }(), 14995 14996 add: function ( color ) { 14997 14998 this.r += color.r; 14999 this.g += color.g; 15000 this.b += color.b; 15001 15002 return this; 15003 15004 }, 15005 15006 addColors: function ( color1, color2 ) { 15007 15008 this.r = color1.r + color2.r; 15009 this.g = color1.g + color2.g; 15010 this.b = color1.b + color2.b; 15011 15012 return this; 15013 15014 }, 15015 15016 addScalar: function ( s ) { 15017 15018 this.r += s; 15019 this.g += s; 15020 this.b += s; 15021 15022 return this; 15023 15024 }, 15025 15026 sub: function ( color ) { 15027 15028 this.r = Math.max( 0, this.r - color.r ); 15029 this.g = Math.max( 0, this.g - color.g ); 15030 this.b = Math.max( 0, this.b - color.b ); 15031 15032 return this; 15033 15034 }, 15035 15036 multiply: function ( color ) { 15037 15038 this.r *= color.r; 15039 this.g *= color.g; 15040 this.b *= color.b; 15041 15042 return this; 15043 15044 }, 15045 15046 multiplyScalar: function ( s ) { 15047 15048 this.r *= s; 15049 this.g *= s; 15050 this.b *= s; 15051 15052 return this; 15053 15054 }, 15055 15056 lerp: function ( color, alpha ) { 15057 15058 this.r += ( color.r - this.r ) * alpha; 15059 this.g += ( color.g - this.g ) * alpha; 15060 this.b += ( color.b - this.b ) * alpha; 15061 15062 return this; 15063 15064 }, 15065 15066 equals: function ( c ) { 15067 15068 return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); 15069 15070 }, 15071 15072 fromArray: function ( array, offset ) { 15073 15074 if ( offset === undefined ) offset = 0; 15075 15076 this.r = array[ offset ]; 15077 this.g = array[ offset + 1 ]; 15078 this.b = array[ offset + 2 ]; 15079 15080 return this; 15081 15082 }, 15083 15084 toArray: function ( array, offset ) { 15085 15086 if ( array === undefined ) array = []; 15087 if ( offset === undefined ) offset = 0; 15088 15089 array[ offset ] = this.r; 15090 array[ offset + 1 ] = this.g; 15091 array[ offset + 2 ] = this.b; 15092 15093 return array; 15094 15095 }, 15096 15097 toJSON: function () { 15098 15099 return this.getHex(); 15100 15101 } 15102 15103 } ); 15104 15105 /** 15106 * Uniforms library for shared webgl shaders 15107 */ 15108 15109 var UniformsLib = { 15110 15111 common: { 15112 15113 diffuse: { value: new Color( 0xeeeeee ) }, 15114 opacity: { value: 1.0 }, 15115 15116 map: { value: null }, 15117 uvTransform: { value: new Matrix3() }, 15118 15119 alphaMap: { value: null }, 15120 15121 }, 15122 15123 specularmap: { 15124 15125 specularMap: { value: null }, 15126 15127 }, 15128 15129 envmap: { 15130 15131 envMap: { value: null }, 15132 flipEnvMap: { value: - 1 }, 15133 reflectivity: { value: 1.0 }, 15134 refractionRatio: { value: 0.98 }, 15135 maxMipLevel: { value: 0 } 15136 15137 }, 15138 15139 aomap: { 15140 15141 aoMap: { value: null }, 15142 aoMapIntensity: { value: 1 } 15143 15144 }, 15145 15146 lightmap: { 15147 15148 lightMap: { value: null }, 15149 lightMapIntensity: { value: 1 } 15150 15151 }, 15152 15153 emissivemap: { 15154 15155 emissiveMap: { value: null } 15156 15157 }, 15158 15159 bumpmap: { 15160 15161 bumpMap: { value: null }, 15162 bumpScale: { value: 1 } 15163 15164 }, 15165 15166 normalmap: { 15167 15168 normalMap: { value: null }, 15169 normalScale: { value: new Vector2( 1, 1 ) } 15170 15171 }, 15172 15173 displacementmap: { 15174 15175 displacementMap: { value: null }, 15176 displacementScale: { value: 1 }, 15177 displacementBias: { value: 0 } 15178 15179 }, 15180 15181 roughnessmap: { 15182 15183 roughnessMap: { value: null } 15184 15185 }, 15186 15187 metalnessmap: { 15188 15189 metalnessMap: { value: null } 15190 15191 }, 15192 15193 gradientmap: { 15194 15195 gradientMap: { value: null } 15196 15197 }, 15198 15199 fog: { 15200 15201 fogDensity: { value: 0.00025 }, 15202 fogNear: { value: 1 }, 15203 fogFar: { value: 2000 }, 15204 fogColor: { value: new Color( 0xffffff ) } 15205 15206 }, 15207 15208 lights: { 15209 15210 ambientLightColor: { value: [] }, 15211 15212 directionalLights: { value: [], properties: { 15213 direction: {}, 15214 color: {}, 15215 15216 shadow: {}, 15217 shadowBias: {}, 15218 shadowRadius: {}, 15219 shadowMapSize: {} 15220 } }, 15221 15222 directionalShadowMap: { value: [] }, 15223 directionalShadowMatrix: { value: [] }, 15224 15225 spotLights: { value: [], properties: { 15226 color: {}, 15227 position: {}, 15228 direction: {}, 15229 distance: {}, 15230 coneCos: {}, 15231 penumbraCos: {}, 15232 decay: {}, 15233 15234 shadow: {}, 15235 shadowBias: {}, 15236 shadowRadius: {}, 15237 shadowMapSize: {} 15238 } }, 15239 15240 spotShadowMap: { value: [] }, 15241 spotShadowMatrix: { value: [] }, 15242 15243 pointLights: { value: [], properties: { 15244 color: {}, 15245 position: {}, 15246 decay: {}, 15247 distance: {}, 15248 15249 shadow: {}, 15250 shadowBias: {}, 15251 shadowRadius: {}, 15252 shadowMapSize: {}, 15253 shadowCameraNear: {}, 15254 shadowCameraFar: {} 15255 } }, 15256 15257 pointShadowMap: { value: [] }, 15258 pointShadowMatrix: { value: [] }, 15259 15260 hemisphereLights: { value: [], properties: { 15261 direction: {}, 15262 skyColor: {}, 15263 groundColor: {} 15264 } }, 15265 15266 // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src 15267 rectAreaLights: { value: [], properties: { 15268 color: {}, 15269 position: {}, 15270 width: {}, 15271 height: {} 15272 } } 15273 15274 }, 15275 15276 points: { 15277 15278 diffuse: { value: new Color( 0xeeeeee ) }, 15279 opacity: { value: 1.0 }, 15280 size: { value: 1.0 }, 15281 scale: { value: 1.0 }, 15282 map: { value: null }, 15283 uvTransform: { value: new Matrix3() } 15284 15285 } 15286 15287 }; 15288 15289 /** 15290 * @author alteredq / http://alteredqualia.com/ 15291 * @author mrdoob / http://mrdoob.com/ 15292 * @author mikael emtinger / http://gomo.se/ 15293 */ 15294 15295 var ShaderLib = { 15296 15297 basic: { 15298 15299 uniforms: UniformsUtils.merge( [ 15300 UniformsLib.common, 15301 UniformsLib.specularmap, 15302 UniformsLib.envmap, 15303 UniformsLib.aomap, 15304 UniformsLib.lightmap, 15305 UniformsLib.fog 15306 ] ), 15307
15308 vertexShader: ShaderChunk.meshbasic_vert, 15309 fragmentShader: ShaderChunk.meshbasic_frag 15310 15311 }, 15312 15313 lambert: { 15314 15315 uniforms: UniformsUtils.merge( [ 15316 UniformsLib.common, 15317 UniformsLib.specularmap, 15318 UniformsLib.envmap, 15319 UniformsLib.aomap, 15320 UniformsLib.lightmap, 15321 UniformsLib.emissivemap, 15322 UniformsLib.fog, 15323 UniformsLib.lights, 15324 { 15325 emissive: { value: new Color( 0x000000 ) } 15326 } 15327 ] ), 15328 15329 vertexShader: ShaderChunk.meshlambert_vert, 15330 fragmentShader: ShaderChunk.meshlambert_frag 15331 15332 }, 15333 15334 phong: { 15335 15336 uniforms: UniformsUtils.merge( [ 15337 UniformsLib.common, 15338 UniformsLib.specularmap, 15339 UniformsLib.envmap, 15340 UniformsLib.aomap, 15341 UniformsLib.lightmap, 15342 UniformsLib.emissivemap, 15343 UniformsLib.bumpmap, 15344 UniformsLib.normalmap, 15345 UniformsLib.displacementmap, 15346 UniformsLib.gradientmap, 15347 UniformsLib.fog, 15348 UniformsLib.lights, 15349 { 15350 emissive: { value: new Color( 0x000000 ) }, 15351 specular: { value: new Color( 0x111111 ) }, 15352 shininess: { value: 30 } 15353 } 15354 ] ), 15355 15356 vertexShader: ShaderChunk.meshphong_vert, 15357 fragmentShader: ShaderChunk.meshphong_frag 15358 15359 }, 15360 15361 standard: { 15362 15363 uniforms: UniformsUtils.merge( [ 15364 UniformsLib.common, 15365 UniformsLib.envmap, 15366 UniformsLib.aomap, 15367 UniformsLib.lightmap, 15368 UniformsLib.emissivemap, 15369 UniformsLib.bumpmap, 15370 UniformsLib.normalmap, 15371 UniformsLib.displacementmap, 15372 UniformsLib.roughnessmap, 15373 UniformsLib.metalnessmap, 15374 UniformsLib.fog, 15375 UniformsLib.lights, 15376 { 15377 emissive: { value: new Color( 0x000000 ) }, 15378 roughness: { value: 0.5 }, 15379 metalness: { value: 0.5 }, 15380 envMapIntensity: { value: 1 } // temporary 15381 } 15382 ] ), 15383 15384 vertexShader: ShaderChunk.meshphysical_vert, 15385 fragmentShader: ShaderChunk.meshphysical_frag 15386 15387 }, 15388 15389 points: { 15390 15391 uniforms: UniformsUtils.merge( [ 15392 UniformsLib.points, 15393 UniformsLib.fog 15394 ] ), 15395
vendor: 2,046 bytes, lines 15396-15502
15396 vertexShader: ShaderChunk.points_vert, 15397 fragmentShader: ShaderChunk.points_frag 15398 15399 }, 15400 15401 dashed: { 15402 15403 uniforms: UniformsUtils.merge( [ 15404 UniformsLib.common, 15405 UniformsLib.fog, 15406 { 15407 scale: { value: 1 }, 15408 dashSize: { value: 1 }, 15409 totalSize: { value: 2 } 15410 } 15411 ] ), 15412 15413 vertexShader: ShaderChunk.linedashed_vert, 15414 fragmentShader: ShaderChunk.linedashed_frag 15415 15416 }, 15417 15418 depth: { 15419 15420 uniforms: UniformsUtils.merge( [ 15421 UniformsLib.common, 15422 UniformsLib.displacementmap 15423 ] ), 15424 15425 vertexShader: ShaderChunk.depth_vert, 15426 fragmentShader: ShaderChunk.depth_frag 15427 15428 }, 15429 15430 normal: { 15431 15432 uniforms: UniformsUtils.merge( [ 15433 UniformsLib.common, 15434 UniformsLib.bumpmap, 15435 UniformsLib.normalmap, 15436 UniformsLib.displacementmap, 15437 { 15438 opacity: { value: 1.0 } 15439 } 15440 ] ), 15441 15442 vertexShader: ShaderChunk.normal_vert, 15443 fragmentShader: ShaderChunk.normal_frag 15444 15445 }, 15446 15447 /* ------------------------------------------------------------------------- 15448 // Cube map shader 15449 ------------------------------------------------------------------------- */ 15450 15451 cube: { 15452 15453 uniforms: { 15454 tCube: { value: null }, 15455 tFlip: { value: - 1 }, 15456 opacity: { value: 1.0 } 15457 }, 15458 15459 vertexShader: ShaderChunk.cube_vert, 15460 fragmentShader: ShaderChunk.cube_frag 15461 15462 }, 15463 15464 equirect: { 15465 15466 uniforms: { 15467 tEquirect: { value: null }, 15468 }, 15469 15470 vertexShader: ShaderChunk.equirect_vert, 15471 fragmentShader: ShaderChunk.equirect_frag 15472 15473 }, 15474 15475 distanceRGBA: { 15476 15477 uniforms: UniformsUtils.merge( [ 15478 UniformsLib.common, 15479 UniformsLib.displacementmap, 15480 { 15481 referencePosition: { value: new Vector3() }, 15482 nearDistance: { value: 1 }, 15483 farDistance: { value: 1000 } 15484 } 15485 ] ), 15486 15487 vertexShader: ShaderChunk.distanceRGBA_vert, 15488 fragmentShader: ShaderChunk.distanceRGBA_frag 15489 15490 }, 15491 15492 shadow: { 15493 15494 uniforms: UniformsUtils.merge( [ 15495 UniformsLib.lights, 15496 UniformsLib.fog, 15497 { 15498 color: { value: new Color( 0x00000 ) }, 15499 opacity: { value: 1.0 } 15500 }, 15501 ] ), 15502
15503 vertexShader: ShaderChunk.shadow_vert, 15504 fragmentShader: ShaderChunk.shadow_frag 15505 15506 } 15507 15508 }; 15509 15510 ShaderLib.physical = { 15511 15512 uniforms: UniformsUtils.merge( [ 15513 ShaderLib.standard.uniforms, 15514 { 15515 clearCoat: { value: 0 }, 15516 clearCoatRoughness: { value: 0 } 15517 } 15518 ] ), 15519 15520 vertexShader: ShaderChunk.meshphysical_vert, 15521 fragmentShader: ShaderChunk.meshphysical_frag 15522 15523 }; 15524 15525 /** 15526 * @author mrdoob / http://mrdoob.com/ 15527 */ 15528 15529 function WebGLAnimation() { 15530 15531 var context = null; 15532 var isAnimating = false; 15533 var animationLoop = null; 15534 15535 function onAnimationFrame( time, frame ) { 15536 15537 if ( isAnimating === false ) return; 15538 15539 animationLoop( time, frame ); 15540 15541 context.requestAnimationFrame( onAnimationFrame ); 15542 15543 } 15544 15545 return { 15546 15547 start: function () { 15548 15549 if ( isAnimating === true ) return; 15550 if ( animationLoop === null ) return; 15551 15552 context.requestAnimationFrame( onAnimationFrame ); 15553 15554 isAnimating = true; 15555 15556 }, 15557 15558 stop: function () { 15559 15560 isAnimating = false; 15561 15562 }, 15563 15564 setAnimationLoop: function ( callback ) { 15565 15566 animationLoop = callback; 15567 15568 }, 15569 15570 setContext: function ( value ) { 15571 15572 context = value; 15573 15574 } 15575 15576 }; 15577 15578 } 15579 15580 /** 15581 * @author mrdoob / http://mrdoob.com/ 15582 */ 15583 15584 function WebGLAttributes( gl ) { 15585 15586 var buffers = new WeakMap(); 15587 15588 function createBuffer( attribute, bufferType ) { 15589 15590 var array = attribute.array; 15591 var usage = attribute.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW; 15592 15593 var buffer = gl.createBuffer(); 15594 15595 gl.bindBuffer( bufferType, buffer ); 15596 gl.bufferData( bufferType, array, usage ); 15597 15598 attribute.onUploadCallback(); 15599 15600 var type = gl.FLOAT; 15601 15602 if ( array instanceof Float32Array ) { 15603 15604 type = gl.FLOAT; 15605 15606 } else if ( array instanceof Float64Array ) { 15607 15608 console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); 15609 15610 } else if ( array instanceof Uint16Array ) { 15611 15612 type = gl.UNSIGNED_SHORT; 15613 15614 } else if ( array instanceof Int16Array ) { 15615 15616 type = gl.SHORT; 15617 15618 } else if ( array instanceof Uint32Array ) { 15619 15620 type = gl.UNSIGNED_INT; 15621 15622 } else if ( array instanceof Int32Array ) { 15623 15624 type = gl.INT; 15625 15626 } else if ( array instanceof Int8Array ) { 15627 15628 type = gl.BYTE; 15629 15630 } else if ( array instanceof Uint8Array ) { 15631 15632 type = gl.UNSIGNED_BYTE; 15633 15634 } 15635 15636 return { 15637 buffer: buffer, 15638 type: type, 15639 bytesPerElement: array.BYTES_PER_ELEMENT, 15640 version: attribute.version 15641 }; 15642 15643 } 15644 15645 function updateBuffer( buffer, attribute, bufferType ) { 15646 15647 var array = attribute.array; 15648 var updateRange = attribute.updateRange; 15649 15650 gl.bindBuffer( bufferType, buffer ); 15651 15652 if ( attribute.dynamic === false ) { 15653 15654 gl.bufferData( bufferType, array, gl.STATIC_DRAW ); 15655 15656 } else if ( updateRange.count === - 1 ) { 15657 15658 // Not using update ranges 15659 15660 gl.bufferSubData( bufferType, 0, array ); 15661 15662 } else if ( updateRange.count === 0 ) { 15663 15664 console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); 15665 15666 } else { 15667 15668 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, 15669 array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); 15670 15671 updateRange.count = - 1; // reset range 15672 15673 } 15674 15675 } 15676 15677 // 15678 15679 function get( attribute ) { 15680 15681 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 15682 15683 return buffers.get( attribute ); 15684 15685 } 15686 15687 function remove( attribute ) { 15688 15689 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 15690 15691 var data = buffers.get( attribute ); 15692 15693 if ( data ) { 15694 15695 gl.deleteBuffer( data.buffer ); 15696 15697 buffers.delete( attribute ); 15698 15699 } 15700 15701 } 15702 15703 function update( attribute, bufferType ) { 15704 15705 if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; 15706 15707 var data = buffers.get( attribute ); 15708 15709 if ( data === undefined ) { 15710 15711 buffers.set( attribute, createBuffer( attribute, bufferType ) ); 15712 15713 } else if ( data.version < attribute.version ) { 15714 15715 updateBuffer( data.buffer, attribute, bufferType ); 15716 15717 data.version = attribute.version; 15718 15719 } 15720 15721 } 15722 15723 return { 15724 15725 get: get, 15726 remove: remove, 15727 update: update 15728 15729 }; 15730 15731 } 15732 15733 /** 15734 * @author mrdoob / http://mrdoob.com/ 15735 * @author WestLangley / http://github.com/WestLangley 15736 * @author bhouston / http://clara.io 15737 */ 15738 15739 function Euler( x, y, z, order ) { 15740 15741 this._x = x || 0; 15742 this._y = y || 0; 15743 this._z = z || 0; 15744 this._order = order || Euler.DefaultOrder; 15745 15746 } 15747 15748 Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; 15749 15750 Euler.DefaultOrder = 'XYZ'; 15751 15752 Object.defineProperties( Euler.prototype, { 15753
vendor: 11,152 bytes, lines 15754-16403
15754 x: { 15755 15756 get: function () { 15757 15758 return this._x; 15759 15760 }, 15761 15762 set: function ( value ) { 15763 15764 this._x = value; 15765 this.onChangeCallback(); 15766 15767 } 15768 15769 }, 15770 15771 y: { 15772 15773 get: function () { 15774 15775 return this._y; 15776 15777 }, 15778 15779 set: function ( value ) { 15780 15781 this._y = value; 15782 this.onChangeCallback(); 15783 15784 } 15785 15786 }, 15787 15788 z: { 15789 15790 get: function () { 15791 15792 return this._z; 15793 15794 }, 15795 15796 set: function ( value ) { 15797 15798 this._z = value; 15799 this.onChangeCallback(); 15800 15801 } 15802 15803 }, 15804 15805 order: { 15806 15807 get: function () { 15808 15809 return this._order; 15810 15811 }, 15812 15813 set: function ( value ) { 15814 15815 this._order = value; 15816 this.onChangeCallback(); 15817 15818 } 15819 15820 } 15821 15822 } ); 15823 15824 Object.assign( Euler.prototype, { 15825 15826 isEuler: true, 15827 15828 set: function ( x, y, z, order ) { 15829 15830 this._x = x; 15831 this._y = y; 15832 this._z = z; 15833 this._order = order || this._order; 15834 15835 this.onChangeCallback(); 15836 15837 return this; 15838 15839 }, 15840 15841 clone: function () { 15842 15843 return new this.constructor( this._x, this._y, this._z, this._order ); 15844 15845 }, 15846 15847 copy: function ( euler ) { 15848 15849 this._x = euler._x; 15850 this._y = euler._y; 15851 this._z = euler._z; 15852 this._order = euler._order; 15853 15854 this.onChangeCallback(); 15855 15856 return this; 15857 15858 }, 15859 15860 setFromRotationMatrix: function ( m, order, update ) { 15861 15862 var clamp = _Math.clamp; 15863 15864 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 15865 15866 var te = m.elements; 15867 var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; 15868 var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; 15869 var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; 15870 15871 order = order || this._order; 15872 15873 if ( order === 'XYZ' ) { 15874 15875 this._y = Math.asin( clamp( m13, - 1, 1 ) ); 15876 15877 if ( Math.abs( m13 ) < 0.99999 ) { 15878 15879 this._x = Math.atan2( - m23, m33 ); 15880 this._z = Math.atan2( - m12, m11 ); 15881 15882 } else { 15883 15884 this._x = Math.atan2( m32, m22 ); 15885 this._z = 0; 15886 15887 } 15888 15889 } else if ( order === 'YXZ' ) { 15890 15891 this._x = Math.asin( - clamp( m23, - 1, 1 ) ); 15892 15893 if ( Math.abs( m23 ) < 0.99999 ) { 15894 15895 this._y = Math.atan2( m13, m33 ); 15896 this._z = Math.atan2( m21, m22 ); 15897 15898 } else { 15899 15900 this._y = Math.atan2( - m31, m11 ); 15901 this._z = 0; 15902 15903 } 15904 15905 } else if ( order === 'ZXY' ) { 15906 15907 this._x = Math.asin( clamp( m32, - 1, 1 ) ); 15908 15909 if ( Math.abs( m32 ) < 0.99999 ) { 15910 15911 this._y = Math.atan2( - m31, m33 ); 15912 this._z = Math.atan2( - m12, m22 ); 15913 15914 } else { 15915 15916 this._y = 0; 15917 this._z = Math.atan2( m21, m11 ); 15918 15919 } 15920 15921 } else if ( order === 'ZYX' ) { 15922 15923 this._y = Math.asin( - clamp( m31, - 1, 1 ) ); 15924 15925 if ( Math.abs( m31 ) < 0.99999 ) { 15926 15927 this._x = Math.atan2( m32, m33 ); 15928 this._z = Math.atan2( m21, m11 ); 15929 15930 } else { 15931 15932 this._x = 0; 15933 this._z = Math.atan2( - m12, m22 ); 15934 15935 } 15936 15937 } else if ( order === 'YZX' ) { 15938 15939 this._z = Math.asin( clamp( m21, - 1, 1 ) ); 15940 15941 if ( Math.abs( m21 ) < 0.99999 ) { 15942 15943 this._x = Math.atan2( - m23, m22 ); 15944 this._y = Math.atan2( - m31, m11 ); 15945 15946 } else { 15947 15948 this._x = 0; 15949 this._y = Math.atan2( m13, m33 ); 15950 15951 } 15952 15953 } else if ( order === 'XZY' ) { 15954 15955 this._z = Math.asin( - clamp( m12, - 1, 1 ) ); 15956 15957 if ( Math.abs( m12 ) < 0.99999 ) { 15958 15959 this._x = Math.atan2( m32, m22 ); 15960 this._y = Math.atan2( m13, m11 ); 15961 15962 } else { 15963 15964 this._x = Math.atan2( - m23, m33 ); 15965 this._y = 0; 15966 15967 } 15968 15969 } else { 15970 15971 console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); 15972 15973 } 15974 15975 this._order = order; 15976 15977 if ( update !== false ) this.onChangeCallback(); 15978 15979 return this; 15980 15981 }, 15982 15983 setFromQuaternion: function () { 15984 15985 var matrix = new Matrix4(); 15986 15987 return function setFromQuaternion( q, order, update ) { 15988 15989 matrix.makeRotationFromQuaternion( q ); 15990 15991 return this.setFromRotationMatrix( matrix, order, update ); 15992 15993 }; 15994 15995 }(), 15996 15997 setFromVector3: function ( v, order ) { 15998 15999 return this.set( v.x, v.y, v.z, order || this._order ); 16000 16001 }, 16002 16003 reorder: function () { 16004 16005 // WARNING: this discards revolution information -bhouston 16006 16007 var q = new Quaternion(); 16008 16009 return function reorder( newOrder ) { 16010 16011 q.setFromEuler( this ); 16012 16013 return this.setFromQuaternion( q, newOrder ); 16014 16015 }; 16016 16017 }(), 16018 16019 equals: function ( euler ) { 16020 16021 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); 16022 16023 }, 16024 16025 fromArray: function ( array ) { 16026 16027 this._x = array[ 0 ]; 16028 this._y = array[ 1 ]; 16029 this._z = array[ 2 ]; 16030 if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; 16031 16032 this.onChangeCallback(); 16033 16034 return this; 16035 16036 }, 16037 16038 toArray: function ( array, offset ) { 16039 16040 if ( array === undefined ) array = []; 16041 if ( offset === undefined ) offset = 0; 16042 16043 array[ offset ] = this._x; 16044 array[ offset + 1 ] = this._y; 16045 array[ offset + 2 ] = this._z; 16046 array[ offset + 3 ] = this._order; 16047 16048 return array; 16049 16050 }, 16051 16052 toVector3: function ( optionalResult ) { 16053 16054 if ( optionalResult ) { 16055 16056 return optionalResult.set( this._x, this._y, this._z ); 16057 16058 } else { 16059 16060 return new Vector3( this._x, this._y, this._z ); 16061 16062 } 16063 16064 }, 16065 16066 onChange: function ( callback ) { 16067 16068 this.onChangeCallback = callback; 16069 16070 return this; 16071 16072 }, 16073 16074 onChangeCallback: function () {} 16075 16076 } ); 16077 16078 /** 16079 * @author mrdoob / http://mrdoob.com/ 16080 */ 16081 16082 function Layers() { 16083 16084 this.mask = 1 | 0; 16085 16086 } 16087 16088 Object.assign( Layers.prototype, { 16089 16090 set: function ( channel ) { 16091 16092 this.mask = 1 << channel | 0; 16093 16094 }, 16095 16096 enable: function ( channel ) { 16097 16098 this.mask |= 1 << channel | 0; 16099 16100 }, 16101 16102 toggle: function ( channel ) { 16103 16104 this.mask ^= 1 << channel | 0; 16105 16106 }, 16107 16108 disable: function ( channel ) { 16109 16110 this.mask &= ~ ( 1 << channel | 0 ); 16111 16112 }, 16113 16114 test: function ( layers ) { 16115 16116 return ( this.mask & layers.mask ) !== 0; 16117 16118 } 16119 16120 } ); 16121 16122 /** 16123 * @author mrdoob / http://mrdoob.com/ 16124 * @author mikael emtinger / http://gomo.se/ 16125 * @author alteredq / http://alteredqualia.com/ 16126 * @author WestLangley / http://github.com/WestLangley 16127 * @author elephantatwork / www.elephantatwork.ch 16128 */ 16129 16130 var object3DId = 0; 16131 16132 function Object3D() { 16133 16134 Object.defineProperty( this, 'id', { value: object3DId ++ } ); 16135 16136 this.uuid = _Math.generateUUID(); 16137 16138 this.name = ''; 16139 this.type = 'Object3D'; 16140 16141 this.parent = null; 16142 this.children = []; 16143 16144 this.up = Object3D.DefaultUp.clone(); 16145 16146 var position = new Vector3(); 16147 var rotation = new Euler(); 16148 var quaternion = new Quaternion(); 16149 var scale = new Vector3( 1, 1, 1 ); 16150 16151 function onRotationChange() { 16152 16153 quaternion.setFromEuler( rotation, false ); 16154 16155 } 16156 16157 function onQuaternionChange() { 16158 16159 rotation.setFromQuaternion( quaternion, undefined, false ); 16160 16161 } 16162 16163 rotation.onChange( onRotationChange ); 16164 quaternion.onChange( onQuaternionChange ); 16165 16166 Object.defineProperties( this, { 16167 position: { 16168 enumerable: true, 16169 value: position 16170 }, 16171 rotation: { 16172 enumerable: true, 16173 value: rotation 16174 }, 16175 quaternion: { 16176 enumerable: true, 16177 value: quaternion 16178 }, 16179 scale: { 16180 enumerable: true, 16181 value: scale 16182 }, 16183 modelViewMatrix: { 16184 value: new Matrix4() 16185 }, 16186 normalMatrix: { 16187 value: new Matrix3() 16188 } 16189 } ); 16190 16191 this.matrix = new Matrix4(); 16192 this.matrixWorld = new Matrix4(); 16193 16194 this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; 16195 this.matrixWorldNeedsUpdate = false; 16196 16197 this.layers = new Layers(); 16198 this.visible = true; 16199 16200 this.castShadow = false; 16201 this.receiveShadow = false; 16202 16203 this.frustumCulled = true; 16204 this.renderOrder = 0; 16205 16206 this.userData = {}; 16207 16208 } 16209 16210 Object3D.DefaultUp = new Vector3( 0, 1, 0 ); 16211 Object3D.DefaultMatrixAutoUpdate = true; 16212 16213 Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 16214 16215 constructor: Object3D, 16216 16217 isObject3D: true, 16218 16219 onBeforeRender: function () {}, 16220 onAfterRender: function () {}, 16221 16222 applyMatrix: function ( matrix ) { 16223 16224 this.matrix.multiplyMatrices( matrix, this.matrix ); 16225 16226 this.matrix.decompose( this.position, this.quaternion, this.scale ); 16227 16228 }, 16229 16230 applyQuaternion: function ( q ) { 16231 16232 this.quaternion.premultiply( q ); 16233 16234 return this; 16235 16236 }, 16237 16238 setRotationFromAxisAngle: function ( axis, angle ) { 16239 16240 // assumes axis is normalized 16241 16242 this.quaternion.setFromAxisAngle( axis, angle ); 16243 16244 }, 16245 16246 setRotationFromEuler: function ( euler ) { 16247 16248 this.quaternion.setFromEuler( euler, true ); 16249 16250 }, 16251 16252 setRotationFromMatrix: function ( m ) { 16253 16254 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) 16255 16256 this.quaternion.setFromRotationMatrix( m ); 16257 16258 }, 16259 16260 setRotationFromQuaternion: function ( q ) { 16261 16262 // assumes q is normalized 16263 16264 this.quaternion.copy( q ); 16265 16266 }, 16267 16268 rotateOnAxis: function () { 16269 16270 // rotate object on axis in object space 16271 // axis is assumed to be normalized 16272 16273 var q1 = new Quaternion(); 16274 16275 return function rotateOnAxis( axis, angle ) { 16276 16277 q1.setFromAxisAngle( axis, angle ); 16278 16279 this.quaternion.multiply( q1 ); 16280 16281 return this; 16282 16283 }; 16284 16285 }(), 16286 16287 rotateOnWorldAxis: function () { 16288 16289 // rotate object on axis in world space 16290 // axis is assumed to be normalized 16291 // method assumes no rotated parent 16292 16293 var q1 = new Quaternion(); 16294 16295 return function rotateOnWorldAxis( axis, angle ) { 16296 16297 q1.setFromAxisAngle( axis, angle ); 16298 16299 this.quaternion.premultiply( q1 ); 16300 16301 return this; 16302 16303 }; 16304 16305 }(), 16306 16307 rotateX: function () { 16308 16309 var v1 = new Vector3( 1, 0, 0 ); 16310 16311 return function rotateX( angle ) { 16312 16313 return this.rotateOnAxis( v1, angle ); 16314 16315 }; 16316 16317 }(), 16318 16319 rotateY: function () { 16320 16321 var v1 = new Vector3( 0, 1, 0 ); 16322 16323 return function rotateY( angle ) { 16324 16325 return this.rotateOnAxis( v1, angle ); 16326 16327 }; 16328 16329 }(), 16330 16331 rotateZ: function () { 16332 16333 var v1 = new Vector3( 0, 0, 1 ); 16334 16335 return function rotateZ( angle ) { 16336 16337 return this.rotateOnAxis( v1, angle ); 16338 16339 }; 16340 16341 }(), 16342 16343 translateOnAxis: function () { 16344 16345 // translate object by distance along axis in object space 16346 // axis is assumed to be normalized 16347 16348 var v1 = new Vector3(); 16349 16350 return function translateOnAxis( axis, distance ) { 16351 16352 v1.copy( axis ).applyQuaternion( this.quaternion ); 16353 16354 this.position.add( v1.multiplyScalar( distance ) ); 16355 16356 return this; 16357 16358 }; 16359 16360 }(), 16361 16362 translateX: function () { 16363 16364 var v1 = new Vector3( 1, 0, 0 ); 16365 16366 return function translateX( distance ) { 16367 16368 return this.translateOnAxis( v1, distance ); 16369 16370 }; 16371 16372 }(), 16373 16374 translateY: function () { 16375 16376 var v1 = new Vector3( 0, 1, 0 ); 16377 16378 return function translateY( distance ) { 16379 16380 return this.translateOnAxis( v1, distance ); 16381 16382 }; 16383 16384 }(), 16385 16386 translateZ: function () { 16387 16388 var v1 = new Vector3( 0, 0, 1 ); 16389 16390 return function translateZ( distance ) { 16391 16392 return this.translateOnAxis( v1, distance ); 16393 16394 }; 16395 16396 }(), 16397 16398 localToWorld: function ( vector ) { 16399 16400 return vector.applyMatrix4( this.matrixWorld ); 16401 16402 }, 16403
16404 worldToLocal: function () { 16405 16406 var m1 = new Matrix4(); 16407 16408 return function worldToLocal( vector ) { 16409 16410 return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); 16411 16412 }; 16413 16414 }(), 16415 16416 lookAt: function () { 16417 16418 // This method does not support objects with rotated and/or translated parent(s) 16419 16420 var m1 = new Matrix4(); 16421 var vector = new Vector3(); 16422 16423 return function lookAt( x, y, z ) { 16424 16425 if ( x.isVector3 ) { 16426 16427 vector.copy( x ); 16428 16429 } else { 16430 16431 vector.set( x, y, z ); 16432 16433 } 16434 16435 if ( this.isCamera ) { 16436 16437 m1.lookAt( this.position, vector, this.up ); 16438 16439 } else { 16440 16441 m1.lookAt( vector, this.position, this.up ); 16442 16443 } 16444 16445 this.quaternion.setFromRotationMatrix( m1 ); 16446 16447 }; 16448 16449 }(), 16450 16451 add: function ( object ) { 16452 16453 if ( arguments.length > 1 ) { 16454 16455 for ( var i = 0; i < arguments.length; i ++ ) { 16456 16457 this.add( arguments[ i ] ); 16458 16459 } 16460 16461 return this; 16462 16463 } 16464 16465 if ( object === this ) { 16466 16467 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); 16468 return this; 16469 16470 } 16471 16472 if ( ( object && object.isObject3D ) ) { 16473 16474 if ( object.parent !== null ) { 16475 16476 object.parent.remove( object ); 16477 16478 } 16479 16480 object.parent = this; 16481 object.dispatchEvent( { type: 'added' } ); 16482 16483 this.children.push( object ); 16484 16485 } else { 16486 16487 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); 16488 16489 } 16490 16491 return this; 16492 16493 }, 16494 16495 remove: function ( object ) { 16496 16497 if ( arguments.length > 1 ) { 16498 16499 for ( var i = 0; i < arguments.length; i ++ ) { 16500 16501 this.remove( arguments[ i ] ); 16502 16503 } 16504 16505 return this; 16506 16507 } 16508 16509 var index = this.children.indexOf( object ); 16510 16511 if ( index !== - 1 ) { 16512 16513 object.parent = null; 16514 16515 object.dispatchEvent( { type: 'removed' } ); 16516 16517 this.children.splice( index, 1 ); 16518 16519 } 16520 16521 return this; 16522 16523 }, 16524 16525 getObjectById: function ( id ) { 16526 16527 return this.getObjectByProperty( 'id', id ); 16528 16529 }, 16530 16531 getObjectByName: function ( name ) { 16532 16533 return this.getObjectByProperty( 'name', name ); 16534 16535 }, 16536 16537 getObjectByProperty: function ( name, value ) { 16538 16539 if ( this[ name ] === value ) return this; 16540 16541 for ( var i = 0, l = this.children.length; i < l; i ++ ) { 16542 16543 var child = this.children[ i ]; 16544 var object = child.getObjectByProperty( name, value ); 16545 16546 if ( object !== undefined ) { 16547 16548 return object; 16549 16550 } 16551 16552 } 16553 16554 return undefined; 16555 16556 }, 16557 16558 getWorldPosition: function ( target ) { 16559 16560 if ( target === undefined ) { 16561 16562 console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); 16563 target = new Vector3(); 16564 16565 } 16566 16567 this.updateMatrixWorld( true ); 16568 16569 return target.setFromMatrixPosition( this.matrixWorld ); 16570 16571 }, 16572 16573 getWorldQuaternion: function () { 16574 16575 var position = new Vector3(); 16576 var scale = new Vector3(); 16577 16578 return function getWorldQuaternion( target ) { 16579 16580 if ( target === undefined ) { 16581 16582 console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); 16583 target = new Quaternion(); 16584 16585 } 16586 16587 this.updateMatrixWorld( true ); 16588 16589 this.matrixWorld.decompose( position, target, scale ); 16590 16591 return target; 16592 16593 }; 16594 16595 }(), 16596 16597 getWorldScale: function () { 16598 16599 var position = new Vector3(); 16600 var quaternion = new Quaternion(); 16601 16602 return function getWorldScale( target ) { 16603 16604 if ( target === undefined ) { 16605 16606 console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); 16607 target = new Vector3(); 16608 16609 } 16610 16611 this.updateMatrixWorld( true ); 16612 16613 this.matrixWorld.decompose( position, quaternion, target ); 16614 16615 return target; 16616 16617 }; 16618 16619 }(), 16620 16621 getWorldDirection: function () { 16622 16623 var quaternion = new Quaternion(); 16624 16625 return function getWorldDirection( target ) { 16626 16627 if ( target === undefined ) { 16628 16629 console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); 16630 target = new Vector3(); 16631 16632 } 16633 16634 this.getWorldQuaternion( quaternion ); 16635 16636 return target.set( 0, 0, 1 ).applyQuaternion( quaternion ); 16637 16638 }; 16639 16640 }(), 16641 16642 raycast: function () {}, 16643 16644 traverse: function ( callback ) { 16645 16646 callback( this ); 16647 16648 var children = this.children; 16649 16650 for ( var i = 0, l = children.length; i < l; i ++ ) { 16651 16652 children[ i ].traverse( callback ); 16653 16654 } 16655 16656 }, 16657
vendor: 6,804 bytes, lines 16658-16982
16658 traverseVisible: function ( callback ) { 16659 16660 if ( this.visible === false ) return; 16661 16662 callback( this ); 16663 16664 var children = this.children; 16665 16666 for ( var i = 0, l = children.length; i < l; i ++ ) { 16667 16668 children[ i ].traverseVisible( callback ); 16669 16670 } 16671 16672 }, 16673 16674 traverseAncestors: function ( callback ) { 16675 16676 var parent = this.parent; 16677 16678 if ( parent !== null ) { 16679 16680 callback( parent ); 16681 16682 parent.traverseAncestors( callback ); 16683 16684 } 16685 16686 }, 16687 16688 updateMatrix: function () { 16689 16690 this.matrix.compose( this.position, this.quaternion, this.scale ); 16691 16692 this.matrixWorldNeedsUpdate = true; 16693 16694 }, 16695 16696 updateMatrixWorld: function ( force ) { 16697 16698 if ( this.matrixAutoUpdate ) this.updateMatrix(); 16699 16700 if ( this.matrixWorldNeedsUpdate || force ) { 16701 16702 if ( this.parent === null ) { 16703 16704 this.matrixWorld.copy( this.matrix ); 16705 16706 } else { 16707 16708 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); 16709 16710 } 16711 16712 this.matrixWorldNeedsUpdate = false; 16713 16714 force = true; 16715 16716 } 16717 16718 // update children 16719 16720 var children = this.children; 16721 16722 for ( var i = 0, l = children.length; i < l; i ++ ) { 16723 16724 children[ i ].updateMatrixWorld( force ); 16725 16726 } 16727 16728 }, 16729 16730 toJSON: function ( meta ) { 16731 16732 // meta is a string when called from JSON.stringify 16733 var isRootObject = ( meta === undefined || typeof meta === 'string' ); 16734 16735 var output = {}; 16736 16737 // meta is a hash used to collect geometries, materials. 16738 // not providing it implies that this is the root object 16739 // being serialized. 16740 if ( isRootObject ) { 16741 16742 // initialize meta obj 16743 meta = { 16744 geometries: {}, 16745 materials: {}, 16746 textures: {}, 16747 images: {}, 16748 shapes: {} 16749 }; 16750 16751 output.metadata = { 16752 version: 4.5, 16753 type: 'Object', 16754 generator: 'Object3D.toJSON' 16755 }; 16756 16757 } 16758 16759 // standard Object3D serialization 16760 16761 var object = {}; 16762 16763 object.uuid = this.uuid; 16764 object.type = this.type; 16765 16766 if ( this.name !== '' ) object.name = this.name; 16767 if ( this.castShadow === true ) object.castShadow = true; 16768 if ( this.receiveShadow === true ) object.receiveShadow = true; 16769 if ( this.visible === false ) object.visible = false; 16770 if ( this.frustumCulled === false ) object.frustumCulled = false; 16771 if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; 16772 if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; 16773 16774 object.matrix = this.matrix.toArray(); 16775 16776 if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; 16777 16778 // 16779 16780 function serialize( library, element ) { 16781 16782 if ( library[ element.uuid ] === undefined ) { 16783 16784 library[ element.uuid ] = element.toJSON( meta ); 16785 16786 } 16787 16788 return element.uuid; 16789 16790 } 16791 16792 if ( this.geometry !== undefined ) { 16793 16794 object.geometry = serialize( meta.geometries, this.geometry ); 16795 16796 var parameters = this.geometry.parameters; 16797 16798 if ( parameters !== undefined && parameters.shapes !== undefined ) { 16799 16800 var shapes = parameters.shapes; 16801 16802 if ( Array.isArray( shapes ) ) { 16803 16804 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 16805 16806 var shape = shapes[ i ]; 16807 16808 serialize( meta.shapes, shape ); 16809 16810 } 16811 16812 } else { 16813 16814 serialize( meta.shapes, shapes ); 16815 16816 } 16817 16818 } 16819 16820 } 16821 16822 if ( this.material !== undefined ) { 16823 16824 if ( Array.isArray( this.material ) ) { 16825 16826 var uuids = []; 16827 16828 for ( var i = 0, l = this.material.length; i < l; i ++ ) { 16829 16830 uuids.push( serialize( meta.materials, this.material[ i ] ) ); 16831 16832 } 16833 16834 object.material = uuids; 16835 16836 } else { 16837 16838 object.material = serialize( meta.materials, this.material ); 16839 16840 } 16841 16842 } 16843 16844 // 16845 16846 if ( this.children.length > 0 ) { 16847 16848 object.children = []; 16849 16850 for ( var i = 0; i < this.children.length; i ++ ) { 16851 16852 object.children.push( this.children[ i ].toJSON( meta ).object ); 16853 16854 } 16855 16856 } 16857 16858 if ( isRootObject ) { 16859 16860 var geometries = extractFromCache( meta.geometries ); 16861 var materials = extractFromCache( meta.materials ); 16862 var textures = extractFromCache( meta.textures ); 16863 var images = extractFromCache( meta.images ); 16864 var shapes = extractFromCache( meta.shapes ); 16865 16866 if ( geometries.length > 0 ) output.geometries = geometries; 16867 if ( materials.length > 0 ) output.materials = materials; 16868 if ( textures.length > 0 ) output.textures = textures; 16869 if ( images.length > 0 ) output.images = images; 16870 if ( shapes.length > 0 ) output.shapes = shapes; 16871 16872 } 16873 16874 output.object = object; 16875 16876 return output; 16877 16878 // extract data from the cache hash 16879 // remove metadata on each item 16880 // and return as array 16881 function extractFromCache( cache ) { 16882 16883 var values = []; 16884 for ( var key in cache ) { 16885 16886 var data = cache[ key ]; 16887 delete data.metadata; 16888 values.push( data ); 16889 16890 } 16891 return values; 16892 16893 } 16894 16895 }, 16896 16897 clone: function ( recursive ) { 16898 16899 return new this.constructor().copy( this, recursive ); 16900 16901 }, 16902 16903 copy: function ( source, recursive ) { 16904 16905 if ( recursive === undefined ) recursive = true; 16906 16907 this.name = source.name; 16908 16909 this.up.copy( source.up ); 16910 16911 this.position.copy( source.position ); 16912 this.quaternion.copy( source.quaternion ); 16913 this.scale.copy( source.scale ); 16914 16915 this.matrix.copy( source.matrix ); 16916 this.matrixWorld.copy( source.matrixWorld ); 16917 16918 this.matrixAutoUpdate = source.matrixAutoUpdate; 16919 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; 16920 16921 this.layers.mask = source.layers.mask; 16922 this.visible = source.visible; 16923 16924 this.castShadow = source.castShadow; 16925 this.receiveShadow = source.receiveShadow; 16926 16927 this.frustumCulled = source.frustumCulled; 16928 this.renderOrder = source.renderOrder; 16929 16930 this.userData = JSON.parse( JSON.stringify( source.userData ) ); 16931 16932 if ( recursive === true ) { 16933 16934 for ( var i = 0; i < source.children.length; i ++ ) { 16935 16936 var child = source.children[ i ]; 16937 this.add( child.clone() ); 16938 16939 } 16940 16941 } 16942 16943 return this; 16944 16945 } 16946 16947 } ); 16948 16949 /** 16950 * @author mrdoob / http://mrdoob.com/ 16951 * @author mikael emtinger / http://gomo.se/ 16952 * @author WestLangley / http://github.com/WestLangley 16953 */ 16954 16955 function Camera() { 16956 16957 Object3D.call( this ); 16958 16959 this.type = 'Camera'; 16960 16961 this.matrixWorldInverse = new Matrix4(); 16962 this.projectionMatrix = new Matrix4(); 16963 16964 } 16965 16966 Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { 16967 16968 constructor: Camera, 16969 16970 isCamera: true, 16971 16972 copy: function ( source, recursive ) { 16973 16974 Object3D.prototype.copy.call( this, source, recursive ); 16975 16976 this.matrixWorldInverse.copy( source.matrixWorldInverse ); 16977 this.projectionMatrix.copy( source.projectionMatrix ); 16978 16979 return this; 16980 16981 }, 16982
16983 getWorldDirection: function () { 16984 16985 var quaternion = new Quaternion(); 16986 16987 return function getWorldDirection( target ) { 16988 16989 if ( target === undefined ) { 16990 16991 console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); 16992 target = new Vector3(); 16993 16994 } 16995 16996 this.getWorldQuaternion( quaternion ); 16997 16998 return target.set( 0, 0, - 1 ).applyQuaternion( quaternion ); 16999 17000 }; 17001 17002 }(), 17003 17004 updateMatrixWorld: function ( force ) { 17005 17006 Object3D.prototype.updateMatrixWorld.call( this, force ); 17007 17008 this.matrixWorldInverse.getInverse( this.matrixWorld ); 17009 17010 }, 17011 17012 clone: function () { 17013 17014 return new this.constructor().copy( this ); 17015 17016 } 17017 17018 } ); 17019 17020 /** 17021 * @author alteredq / http://alteredqualia.com/ 17022 * @author arose / http://github.com/arose 17023 */ 17024 17025 function OrthographicCamera( left, right, top, bottom, near, far ) { 17026 17027 Camera.call( this ); 17028 17029 this.type = 'OrthographicCamera'; 17030 17031 this.zoom = 1; 17032 this.view = null; 17033 17034 this.left = left; 17035 this.right = right; 17036 this.top = top; 17037 this.bottom = bottom; 17038 17039 this.near = ( near !== undefined ) ? near : 0.1; 17040 this.far = ( far !== undefined ) ? far : 2000; 17041 17042 this.updateProjectionMatrix(); 17043 17044 } 17045 17046 OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), { 17047 17048 constructor: OrthographicCamera, 17049 17050 isOrthographicCamera: true, 17051 17052 copy: function ( source, recursive ) { 17053 17054 Camera.prototype.copy.call( this, source, recursive ); 17055 17056 this.left = source.left; 17057 this.right = source.right; 17058 this.top = source.top; 17059 this.bottom = source.bottom; 17060 this.near = source.near; 17061 this.far = source.far; 17062 17063 this.zoom = source.zoom; 17064 this.view = source.view === null ? null : Object.assign( {}, source.view ); 17065 17066 return this; 17067 17068 }, 17069 17070 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { 17071 17072 if ( this.view === null ) { 17073 17074 this.view = { 17075 enabled: true, 17076 fullWidth: 1, 17077 fullHeight: 1, 17078 offsetX: 0, 17079 offsetY: 0, 17080 width: 1, 17081 height: 1 17082 }; 17083 17084 } 17085 17086 this.view.enabled = true; 17087 this.view.fullWidth = fullWidth; 17088 this.view.fullHeight = fullHeight; 17089 this.view.offsetX = x; 17090 this.view.offsetY = y; 17091 this.view.width = width; 17092 this.view.height = height; 17093 17094 this.updateProjectionMatrix(); 17095 17096 }, 17097 17098 clearViewOffset: function () { 17099 17100 if ( this.view !== null ) { 17101 17102 this.view.enabled = false; 17103 17104 } 17105 17106 this.updateProjectionMatrix(); 17107 17108 }, 17109 17110 updateProjectionMatrix: function () { 17111 17112 var dx = ( this.right - this.left ) / ( 2 * this.zoom ); 17113 var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); 17114 var cx = ( this.right + this.left ) / 2; 17115 var cy = ( this.top + this.bottom ) / 2; 17116 17117 var left = cx - dx; 17118 var right = cx + dx; 17119 var top = cy + dy; 17120 var bottom = cy - dy; 17121 17122 if ( this.view !== null && this.view.enabled ) { 17123 17124 var zoomW = this.zoom / ( this.view.width / this.view.fullWidth ); 17125 var zoomH = this.zoom / ( this.view.height / this.view.fullHeight ); 17126 var scaleW = ( this.right - this.left ) / this.view.width; 17127 var scaleH = ( this.top - this.bottom ) / this.view.height; 17128 17129 left += scaleW * ( this.view.offsetX / zoomW ); 17130 right = left + scaleW * ( this.view.width / zoomW ); 17131 top -= scaleH * ( this.view.offsetY / zoomH ); 17132 bottom = top - scaleH * ( this.view.height / zoomH ); 17133 17134 } 17135 17136 this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); 17137 17138 }, 17139 17140 toJSON: function ( meta ) { 17141 17142 var data = Object3D.prototype.toJSON.call( this, meta ); 17143 17144 data.object.zoom = this.zoom; 17145 data.object.left = this.left; 17146 data.object.right = this.right; 17147 data.object.top = this.top; 17148 data.object.bottom = this.bottom; 17149 data.object.near = this.near; 17150 data.object.far = this.far; 17151 17152 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); 17153 17154 return data; 17155 17156 } 17157 17158 } ); 17159 17160 /** 17161 * @author mrdoob / http://mrdoob.com/ 17162 * @author alteredq / http://alteredqualia.com/ 17163 */ 17164 17165 function Face3( a, b, c, normal, color, materialIndex ) { 17166 17167 this.a = a; 17168 this.b = b; 17169 this.c = c; 17170 17171 this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); 17172 this.vertexNormals = Array.isArray( normal ) ? normal : []; 17173 17174 this.color = ( color && color.isColor ) ? color : new Color(); 17175 this.vertexColors = Array.isArray( color ) ? color : []; 17176 17177 this.materialIndex = materialIndex !== undefined ? materialIndex : 0; 17178 17179 } 17180 17181 Object.assign( Face3.prototype, { 17182
17183 clone: function () { 17184 17185 return new this.constructor().copy( this ); 17186 17187 }, 17188 17189 copy: function ( source ) { 17190 17191 this.a = source.a; 17192 this.b = source.b; 17193 this.c = source.c; 17194 17195 this.normal.copy( source.normal ); 17196 this.color.copy( source.color ); 17197 17198 this.materialIndex = source.materialIndex; 17199 17200 for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { 17201 17202 this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); 17203 17204 } 17205 17206 for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { 17207 17208 this.vertexColors[ i ] = source.vertexColors[ i ].clone(); 17209 17210 } 17211 17212 return this; 17213 17214 } 17215 17216 } ); 17217 17218 /** 17219 * @author mrdoob / http://mrdoob.com/ 17220 * @author kile / http://kile.stravaganza.org/ 17221 * @author alteredq / http://alteredqualia.com/ 17222 * @author mikael emtinger / http://gomo.se/ 17223 * @author zz85 / http://www.lab4games.net/zz85/blog 17224 * @author bhouston / http://clara.io 17225 */ 17226 17227 var geometryId = 0; // Geometry uses even numbers as Id 17228 17229 function Geometry() { 17230 17231 Object.defineProperty( this, 'id', { value: geometryId += 2 } ); 17232 17233 this.uuid = _Math.generateUUID(); 17234 17235 this.name = ''; 17236 this.type = 'Geometry'; 17237 17238 this.vertices = []; 17239 this.colors = []; 17240 this.faces = []; 17241 this.faceVertexUvs = [[]]; 17242 17243 this.morphTargets = []; 17244 this.morphNormals = []; 17245 17246 this.skinWeights = []; 17247 this.skinIndices = []; 17248 17249 this.lineDistances = []; 17250 17251 this.boundingBox = null; 17252 this.boundingSphere = null; 17253 17254 // update flags 17255 17256 this.elementsNeedUpdate = false; 17257 this.verticesNeedUpdate = false; 17258 this.uvsNeedUpdate = false; 17259 this.normalsNeedUpdate = false; 17260 this.colorsNeedUpdate = false; 17261 this.lineDistancesNeedUpdate = false; 17262 this.groupsNeedUpdate = false; 17263 17264 } 17265 17266 Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 17267 17268 constructor: Geometry, 17269 17270 isGeometry: true, 17271 17272 applyMatrix: function ( matrix ) { 17273 17274 var normalMatrix = new Matrix3().getNormalMatrix( matrix ); 17275 17276 for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { 17277 17278 var vertex = this.vertices[ i ]; 17279 vertex.applyMatrix4( matrix ); 17280 17281 } 17282 17283 for ( var i = 0, il = this.faces.length; i < il; i ++ ) { 17284 17285 var face = this.faces[ i ]; 17286 face.normal.applyMatrix3( normalMatrix ).normalize(); 17287 17288 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { 17289 17290 face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); 17291 17292 } 17293 17294 } 17295 17296 if ( this.boundingBox !== null ) { 17297 17298 this.computeBoundingBox(); 17299 17300 } 17301 17302 if ( this.boundingSphere !== null ) { 17303 17304 this.computeBoundingSphere(); 17305 17306 } 17307 17308 this.verticesNeedUpdate = true; 17309 this.normalsNeedUpdate = true; 17310 17311 return this; 17312 17313 }, 17314 17315 rotateX: function () { 17316 17317 // rotate geometry around world x-axis 17318 17319 var m1 = new Matrix4(); 17320 17321 return function rotateX( angle ) { 17322 17323 m1.makeRotationX( angle ); 17324 17325 this.applyMatrix( m1 ); 17326 17327 return this; 17328 17329 }; 17330 17331 }(), 17332 17333 rotateY: function () { 17334 17335 // rotate geometry around world y-axis 17336 17337 var m1 = new Matrix4(); 17338 17339 return function rotateY( angle ) { 17340 17341 m1.makeRotationY( angle ); 17342 17343 this.applyMatrix( m1 ); 17344 17345 return this; 17346 17347 }; 17348 17349 }(), 17350 17351 rotateZ: function () { 17352 17353 // rotate geometry around world z-axis 17354 17355 var m1 = new Matrix4(); 17356 17357 return function rotateZ( angle ) { 17358 17359 m1.makeRotationZ( angle ); 17360 17361 this.applyMatrix( m1 ); 17362 17363 return this; 17364 17365 }; 17366 17367 }(), 17368 17369 translate: function () { 17370 17371 // translate geometry 17372 17373 var m1 = new Matrix4(); 17374 17375 return function translate( x, y, z ) { 17376 17377 m1.makeTranslation( x, y, z ); 17378 17379 this.applyMatrix( m1 ); 17380 17381 return this; 17382 17383 }; 17384 17385 }(), 17386 17387 scale: function () { 17388 17389 // scale geometry 17390 17391 var m1 = new Matrix4(); 17392 17393 return function scale( x, y, z ) { 17394 17395 m1.makeScale( x, y, z ); 17396 17397 this.applyMatrix( m1 ); 17398 17399 return this; 17400 17401 }; 17402 17403 }(), 17404 17405 lookAt: function () { 17406 17407 var obj = new Object3D(); 17408 17409 return function lookAt( vector ) { 17410 17411 obj.lookAt( vector ); 17412 17413 obj.updateMatrix(); 17414 17415 this.applyMatrix( obj.matrix ); 17416 17417 }; 17418 17419 }(), 17420 17421 fromBufferGeometry: function ( geometry ) { 17422 17423 var scope = this; 17424 17425 var indices = geometry.index !== null ? geometry.index.array : undefined; 17426 var attributes = geometry.attributes; 17427 17428 var positions = attributes.position.array; 17429 var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; 17430 var colors = attributes.color !== undefined ? attributes.color.array : undefined; 17431 var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; 17432 var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; 17433 17434 if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; 17435 17436 var tempNormals = []; 17437 var tempUVs = []; 17438 var tempUVs2 = []; 17439 17440 for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) { 17441 17442 scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) ); 17443 17444 if ( normals !== undefined ) { 17445 17446 tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) ); 17447 17448 } 17449 17450 if ( colors !== undefined ) { 17451 17452 scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) ); 17453 17454 } 17455 17456 if ( uvs !== undefined ) { 17457 17458 tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) ); 17459 17460 } 17461 17462 if ( uvs2 !== undefined ) { 17463 17464 tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) ); 17465 17466 } 17467 17468 } 17469 17470 function addFace( a, b, c, materialIndex ) { 17471 17472 var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].
vendor: 54,468 bytes, lines 17472-20120
17472clone(), tempNormals[ c ].clone() ] : []; 17473 var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : []; 17474 17475 var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); 17476 17477 scope.faces.push( face ); 17478 17479 if ( uvs !== undefined ) { 17480 17481 scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] ); 17482 17483 } 17484 17485 if ( uvs2 !== undefined ) { 17486 17487 scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] ); 17488 17489 } 17490 17491 } 17492 17493 var groups = geometry.groups; 17494 17495 if ( groups.length > 0 ) { 17496 17497 for ( var i = 0; i < groups.length; i ++ ) { 17498 17499 var group = groups[ i ]; 17500 17501 var start = group.start; 17502 var count = group.count; 17503 17504 for ( var j = start, jl = start + count; j < jl; j += 3 ) { 17505 17506 if ( indices !== undefined ) { 17507 17508 addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); 17509 17510 } else { 17511 17512 addFace( j, j + 1, j + 2, group.materialIndex ); 17513 17514 } 17515 17516 } 17517 17518 } 17519 17520 } else { 17521 17522 if ( indices !== undefined ) { 17523 17524 for ( var i = 0; i < indices.length; i += 3 ) { 17525 17526 addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); 17527 17528 } 17529 17530 } else { 17531 17532 for ( var i = 0; i < positions.length / 3; i += 3 ) { 17533 17534 addFace( i, i + 1, i + 2 ); 17535 17536 } 17537 17538 } 17539 17540 } 17541 17542 this.computeFaceNormals(); 17543 17544 if ( geometry.boundingBox !== null ) { 17545 17546 this.boundingBox = geometry.boundingBox.clone(); 17547 17548 } 17549 17550 if ( geometry.boundingSphere !== null ) { 17551 17552 this.boundingSphere = geometry.boundingSphere.clone(); 17553 17554 } 17555 17556 return this; 17557 17558 }, 17559 17560 center: function () { 17561 17562 var offset = new Vector3(); 17563 17564 return function center() { 17565 17566 this.computeBoundingBox(); 17567 17568 this.boundingBox.getCenter( offset ).negate(); 17569 17570 this.translate( offset.x, offset.y, offset.z ); 17571 17572 return this; 17573 17574 }; 17575 17576 }(), 17577 17578 normalize: function () { 17579 17580 this.computeBoundingSphere(); 17581 17582 var center = this.boundingSphere.center; 17583 var radius = this.boundingSphere.radius; 17584 17585 var s = radius === 0 ? 1 : 1.0 / radius; 17586 17587 var matrix = new Matrix4(); 17588 matrix.set( 17589 s, 0, 0, - s * center.x, 17590 0, s, 0, - s * center.y, 17591 0, 0, s, - s * center.z, 17592 0, 0, 0, 1 17593 ); 17594 17595 this.applyMatrix( matrix ); 17596 17597 return this; 17598 17599 }, 17600 17601 computeFaceNormals: function () { 17602 17603 var cb = new Vector3(), ab = new Vector3(); 17604 17605 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { 17606 17607 var face = this.faces[ f ]; 17608 17609 var vA = this.vertices[ face.a ]; 17610 var vB = this.vertices[ face.b ]; 17611 var vC = this.vertices[ face.c ]; 17612 17613 cb.subVectors( vC, vB ); 17614 ab.subVectors( vA, vB ); 17615 cb.cross( ab ); 17616 17617 cb.normalize(); 17618 17619 face.normal.copy( cb ); 17620 17621 } 17622 17623 }, 17624 17625 computeVertexNormals: function ( areaWeighted ) { 17626 17627 if ( areaWeighted === undefined ) areaWeighted = true; 17628 17629 var v, vl, f, fl, face, vertices; 17630 17631 vertices = new Array( this.vertices.length ); 17632 17633 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { 17634 17635 vertices[ v ] = new Vector3(); 17636 17637 } 17638 17639 if ( areaWeighted ) { 17640 17641 // vertex normals weighted by triangle areas 17642 // http://www.iquilezles.org/www/articles/normals/normals.htm 17643 17644 var vA, vB, vC; 17645 var cb = new Vector3(), ab = new Vector3(); 17646 17647 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17648 17649 face = this.faces[ f ]; 17650 17651 vA = this.vertices[ face.a ]; 17652 vB = this.vertices[ face.b ]; 17653 vC = this.vertices[ face.c ]; 17654 17655 cb.subVectors( vC, vB ); 17656 ab.subVectors( vA, vB ); 17657 cb.cross( ab ); 17658 17659 vertices[ face.a ].add( cb ); 17660 vertices[ face.b ].add( cb ); 17661 vertices[ face.c ].add( cb ); 17662 17663 } 17664 17665 } else { 17666 17667 this.computeFaceNormals(); 17668 17669 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17670 17671 face = this.faces[ f ]; 17672 17673 vertices[ face.a ].add( face.normal ); 17674 vertices[ face.b ].add( face.normal ); 17675 vertices[ face.c ].add( face.normal ); 17676 17677 } 17678 17679 } 17680 17681 for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { 17682 17683 vertices[ v ].normalize(); 17684 17685 } 17686 17687 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17688 17689 face = this.faces[ f ]; 17690 17691 var vertexNormals = face.vertexNormals; 17692 17693 if ( vertexNormals.length === 3 ) { 17694 17695 vertexNormals[ 0 ].copy( vertices[ face.a ] ); 17696 vertexNormals[ 1 ].copy( vertices[ face.b ] ); 17697 vertexNormals[ 2 ].copy( vertices[ face.c ] ); 17698 17699 } else { 17700 17701 vertexNormals[ 0 ] = vertices[ face.a ].clone(); 17702 vertexNormals[ 1 ] = vertices[ face.b ].clone(); 17703 vertexNormals[ 2 ] = vertices[ face.c ].clone(); 17704 17705 } 17706 17707 } 17708 17709 if ( this.faces.length > 0 ) { 17710 17711 this.normalsNeedUpdate = true; 17712 17713 } 17714 17715 }, 17716 17717 computeFlatVertexNormals: function () { 17718 17719 var f, fl, face; 17720 17721 this.computeFaceNormals(); 17722 17723 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17724 17725 face = this.faces[ f ]; 17726 17727 var vertexNormals = face.vertexNormals; 17728 17729 if ( vertexNormals.length === 3 ) { 17730 17731 vertexNormals[ 0 ].copy( face.normal ); 17732 vertexNormals[ 1 ].copy( face.normal ); 17733 vertexNormals[ 2 ].copy( face.normal ); 17734 17735 } else { 17736 17737 vertexNormals[ 0 ] = face.normal.clone(); 17738 vertexNormals[ 1 ] = face.normal.clone(); 17739 vertexNormals[ 2 ] = face.normal.clone(); 17740 17741 } 17742 17743 } 17744 17745 if ( this.faces.length > 0 ) { 17746 17747 this.normalsNeedUpdate = true; 17748 17749 } 17750 17751 }, 17752 17753 computeMorphNormals: function () { 17754 17755 var i, il, f, fl, face; 17756 17757 // save original normals 17758 // - create temp variables on first access 17759 // otherwise just copy (for faster repeated calls) 17760 17761 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17762 17763 face = this.faces[ f ]; 17764 17765 if ( ! face.__originalFaceNormal ) { 17766 17767 face.__originalFaceNormal = face.normal.clone(); 17768 17769 } else { 17770 17771 face.__originalFaceNormal.copy( face.normal ); 17772 17773 } 17774 17775 if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; 17776 17777 for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { 17778 17779 if ( ! face.__originalVertexNormals[ i ] ) { 17780 17781 face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); 17782 17783 } else { 17784 17785 face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); 17786 17787 } 17788 17789 } 17790 17791 } 17792 17793 // use temp geometry to compute face and vertex normals for each morph 17794 17795 var tmpGeo = new Geometry(); 17796 tmpGeo.faces = this.faces; 17797 17798 for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { 17799 17800 // create on first access 17801 17802 if ( ! this.morphNormals[ i ] ) { 17803 17804 this.morphNormals[ i ] = {}; 17805 this.morphNormals[ i ].faceNormals = []; 17806 this.morphNormals[ i ].vertexNormals = []; 17807 17808 var dstNormalsFace = this.morphNormals[ i ].faceNormals; 17809 var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; 17810 17811 var faceNormal, vertexNormals; 17812 17813 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17814 17815 faceNormal = new Vector3(); 17816 vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; 17817 17818 dstNormalsFace.push( faceNormal ); 17819 dstNormalsVertex.push( vertexNormals ); 17820 17821 } 17822 17823 } 17824 17825 var morphNormals = this.morphNormals[ i ]; 17826 17827 // set vertices to morph target 17828 17829 tmpGeo.vertices = this.morphTargets[ i ].vertices; 17830 17831 // compute morph normals 17832 17833 tmpGeo.computeFaceNormals(); 17834 tmpGeo.computeVertexNormals(); 17835 17836 // store morph normals 17837 17838 var faceNormal, vertexNormals; 17839 17840 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17841 17842 face = this.faces[ f ]; 17843 17844 faceNormal = morphNormals.faceNormals[ f ]; 17845 vertexNormals = morphNormals.vertexNormals[ f ]; 17846 17847 faceNormal.copy( face.normal ); 17848 17849 vertexNormals.a.copy( face.vertexNormals[ 0 ] ); 17850 vertexNormals.b.copy( face.vertexNormals[ 1 ] ); 17851 vertexNormals.c.copy( face.vertexNormals[ 2 ] ); 17852 17853 } 17854 17855 } 17856 17857 // restore original normals 17858 17859 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { 17860 17861 face = this.faces[ f ]; 17862 17863 face.normal = face.__originalFaceNormal; 17864 face.vertexNormals = face.__originalVertexNormals; 17865 17866 } 17867 17868 }, 17869 17870 computeBoundingBox: function () { 17871 17872 if ( this.boundingBox === null ) { 17873 17874 this.boundingBox = new Box3(); 17875 17876 } 17877 17878 this.boundingBox.setFromPoints( this.vertices ); 17879 17880 }, 17881 17882 computeBoundingSphere: function () { 17883 17884 if ( this.boundingSphere === null ) { 17885 17886 this.boundingSphere = new Sphere(); 17887 17888 } 17889 17890 this.boundingSphere.setFromPoints( this.vertices ); 17891 17892 }, 17893 17894 merge: function ( geometry, matrix, materialIndexOffset ) { 17895 17896 if ( ! ( geometry && geometry.isGeometry ) ) { 17897 17898 console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); 17899 return; 17900 17901 } 17902 17903 var normalMatrix, 17904 vertexOffset = this.vertices.length, 17905 vertices1 = this.vertices, 17906 vertices2 = geometry.vertices, 17907 faces1 = this.faces, 17908 faces2 = geometry.faces, 17909 uvs1 = this.faceVertexUvs[ 0 ], 17910 uvs2 = geometry.faceVertexUvs[ 0 ], 17911 colors1 = this.colors, 17912 colors2 = geometry.colors; 17913 17914 if ( materialIndexOffset === undefined ) materialIndexOffset = 0; 17915 17916 if ( matrix !== undefined ) { 17917 17918 normalMatrix = new Matrix3().getNormalMatrix( matrix ); 17919 17920 } 17921 17922 // vertices 17923 17924 for ( var i = 0, il = vertices2.length; i < il; i ++ ) { 17925 17926 var vertex = vertices2[ i ]; 17927 17928 var vertexCopy = vertex.clone(); 17929 17930 if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); 17931 17932 vertices1.push( vertexCopy ); 17933 17934 } 17935 17936 // colors 17937 17938 for ( var i = 0, il = colors2.length; i < il; i ++ ) { 17939 17940 colors1.push( colors2[ i ].clone() ); 17941 17942 } 17943 17944 // faces 17945 17946 for ( i = 0, il = faces2.length; i < il; i ++ ) { 17947 17948 var face = faces2[ i ], faceCopy, normal, color, 17949 faceVertexNormals = face.vertexNormals, 17950 faceVertexColors = face.vertexColors; 17951 17952 faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); 17953 faceCopy.normal.copy( face.normal ); 17954 17955 if ( normalMatrix !== undefined ) { 17956 17957 faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); 17958 17959 } 17960 17961 for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { 17962 17963 normal = faceVertexNormals[ j ].clone(); 17964 17965 if ( normalMatrix !== undefined ) { 17966 17967 normal.applyMatrix3( normalMatrix ).normalize(); 17968 17969 } 17970 17971 faceCopy.vertexNormals.push( normal ); 17972 17973 } 17974 17975 faceCopy.color.copy( face.color ); 17976 17977 for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { 17978 17979 color = faceVertexColors[ j ]; 17980 faceCopy.vertexColors.push( color.clone() ); 17981 17982 } 17983 17984 faceCopy.materialIndex = face.materialIndex + materialIndexOffset; 17985 17986 faces1.push( faceCopy ); 17987 17988 } 17989 17990 // uvs 17991 17992 for ( i = 0, il = uvs2.length; i < il; i ++ ) { 17993 17994 var uv = uvs2[ i ], uvCopy = []; 17995 17996 if ( uv === undefined ) { 17997 17998 continue; 17999 18000 } 18001 18002 for ( var j = 0, jl = uv.length; j < jl; j ++ ) { 18003 18004 uvCopy.push( uv[ j ].clone() ); 18005 18006 } 18007 18008 uvs1.push( uvCopy ); 18009 18010 } 18011 18012 }, 18013 18014 mergeMesh: function ( mesh ) { 18015 18016 if ( ! ( mesh && mesh.isMesh ) ) { 18017 18018 console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); 18019 return; 18020 18021 } 18022 18023 if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); 18024 18025 this.merge( mesh.geometry, mesh.matrix ); 18026 18027 }, 18028 18029 /* 18030 * Checks for duplicate vertices with hashmap. 18031 * Duplicated vertices are removed 18032 * and faces' vertices are updated. 18033 */ 18034 18035 mergeVertices: function () { 18036 18037 var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) 18038 var unique = [], changes = []; 18039 18040 var v, key; 18041 var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 18042 var precision = Math.pow( 10, precisionPoints ); 18043 var i, il, face; 18044 var indices, j, jl; 18045 18046 for ( i = 0, il = this.vertices.length; i < il; i ++ ) { 18047 18048 v = this.vertices[ i ]; 18049 key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); 18050 18051 if ( verticesMap[ key ] === undefined ) { 18052 18053 verticesMap[ key ] = i; 18054 unique.push( this.vertices[ i ] ); 18055 changes[ i ] = unique.length - 1; 18056 18057 } else { 18058 18059 //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); 18060 changes[ i ] = changes[ verticesMap[ key ] ]; 18061 18062 } 18063 18064 } 18065 18066 18067 // if faces are completely degenerate after merging vertices, we 18068 // have to remove them from the geometry. 18069 var faceIndicesToRemove = []; 18070 18071 for ( i = 0, il = this.faces.length; i < il; i ++ ) { 18072 18073 face = this.faces[ i ]; 18074 18075 face.a = changes[ face.a ]; 18076 face.b = changes[ face.b ]; 18077 face.c = changes[ face.c ]; 18078 18079 indices = [ face.a, face.b, face.c ]; 18080 18081 // if any duplicate vertices are found in a Face3 18082 // we have to remove the face as nothing can be saved 18083 for ( var n = 0; n < 3; n ++ ) { 18084 18085 if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { 18086 18087 faceIndicesToRemove.push( i ); 18088 break; 18089 18090 } 18091 18092 } 18093 18094 } 18095 18096 for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { 18097 18098 var idx = faceIndicesToRemove[ i ]; 18099 18100 this.faces.splice( idx, 1 ); 18101 18102 for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { 18103 18104 this.faceVertexUvs[ j ].splice( idx, 1 ); 18105 18106 } 18107 18108 } 18109 18110 // Use unique set of vertices 18111 18112 var diff = this.vertices.length - unique.length; 18113 this.vertices = unique; 18114 return diff; 18115 18116 }, 18117 18118 setFromPoints: function ( points ) { 18119 18120 this.vertices = []; 18121 18122 for ( var i = 0, l = points.length; i < l; i ++ ) { 18123 18124 var point = points[ i ]; 18125 this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); 18126 18127 } 18128 18129 return this; 18130 18131 }, 18132 18133 sortFacesByMaterialIndex: function () { 18134 18135 var faces = this.faces; 18136 var length = faces.length; 18137 18138 // tag faces 18139 18140 for ( var i = 0; i < length; i ++ ) { 18141 18142 faces[ i ]._id = i; 18143 18144 } 18145 18146 // sort faces 18147 18148 function materialIndexSort( a, b ) { 18149 18150 return a.materialIndex - b.materialIndex; 18151 18152 } 18153 18154 faces.sort( materialIndexSort ); 18155 18156 // sort uvs 18157 18158 var uvs1 = this.faceVertexUvs[ 0 ]; 18159 var uvs2 = this.faceVertexUvs[ 1 ]; 18160 18161 var newUvs1, newUvs2; 18162 18163 if ( uvs1 && uvs1.length === length ) newUvs1 = []; 18164 if ( uvs2 && uvs2.length === length ) newUvs2 = []; 18165 18166 for ( var i = 0; i < length; i ++ ) { 18167 18168 var id = faces[ i ]._id; 18169 18170 if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); 18171 if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); 18172 18173 } 18174 18175 if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; 18176 if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; 18177 18178 }, 18179 18180 toJSON: function () { 18181 18182 var data = { 18183 metadata: { 18184 version: 4.5, 18185 type: 'Geometry', 18186 generator: 'Geometry.toJSON' 18187 } 18188 }; 18189 18190 // standard Geometry serialization 18191 18192 data.uuid = this.uuid; 18193 data.type = this.type; 18194 if ( this.name !== '' ) data.name = this.name; 18195 18196 if ( this.parameters !== undefined ) { 18197 18198 var parameters = this.parameters; 18199 18200 for ( var key in parameters ) { 18201 18202 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; 18203 18204 } 18205 18206 return data; 18207 18208 } 18209 18210 var vertices = []; 18211 18212 for ( var i = 0; i < this.vertices.length; i ++ ) { 18213 18214 var vertex = this.vertices[ i ]; 18215 vertices.push( vertex.x, vertex.y, vertex.z ); 18216 18217 } 18218 18219 var faces = []; 18220 var normals = []; 18221 var normalsHash = {}; 18222 var colors = []; 18223 var colorsHash = {}; 18224 var uvs = []; 18225 var uvsHash = {}; 18226 18227 for ( var i = 0; i < this.faces.length; i ++ ) { 18228 18229 var face = this.faces[ i ]; 18230 18231 var hasMaterial = true; 18232 var hasFaceUv = false; // deprecated 18233 var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; 18234 var hasFaceNormal = face.normal.length() > 0; 18235 var hasFaceVertexNormal = face.vertexNormals.length > 0; 18236 var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; 18237 var hasFaceVertexColor = face.vertexColors.length > 0; 18238 18239 var faceType = 0; 18240 18241 faceType = setBit( faceType, 0, 0 ); // isQuad 18242 faceType = setBit( faceType, 1, hasMaterial ); 18243 faceType = setBit( faceType, 2, hasFaceUv ); 18244 faceType = setBit( faceType, 3, hasFaceVertexUv ); 18245 faceType = setBit( faceType, 4, hasFaceNormal ); 18246 faceType = setBit( faceType, 5, hasFaceVertexNormal ); 18247 faceType = setBit( faceType, 6, hasFaceColor ); 18248 faceType = setBit( faceType, 7, hasFaceVertexColor ); 18249 18250 faces.push( faceType ); 18251 faces.push( face.a, face.b, face.c ); 18252 faces.push( face.materialIndex ); 18253 18254 if ( hasFaceVertexUv ) { 18255 18256 var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; 18257 18258 faces.push( 18259 getUvIndex( faceVertexUvs[ 0 ] ), 18260 getUvIndex( faceVertexUvs[ 1 ] ), 18261 getUvIndex( faceVertexUvs[ 2 ] ) 18262 ); 18263 18264 } 18265 18266 if ( hasFaceNormal ) { 18267 18268 faces.push( getNormalIndex( face.normal ) ); 18269 18270 } 18271 18272 if ( hasFaceVertexNormal ) { 18273 18274 var vertexNormals = face.vertexNormals; 18275 18276 faces.push( 18277 getNormalIndex( vertexNormals[ 0 ] ), 18278 getNormalIndex( vertexNormals[ 1 ] ), 18279 getNormalIndex( vertexNormals[ 2 ] ) 18280 ); 18281 18282 } 18283 18284 if ( hasFaceColor ) { 18285 18286 faces.push( getColorIndex( face.color ) ); 18287 18288 } 18289 18290 if ( hasFaceVertexColor ) { 18291 18292 var vertexColors = face.vertexColors; 18293 18294 faces.push( 18295 getColorIndex( vertexColors[ 0 ] ), 18296 getColorIndex( vertexColors[ 1 ] ), 18297 getColorIndex( vertexColors[ 2 ] ) 18298 ); 18299 18300 } 18301 18302 } 18303 18304 function setBit( value, position, enabled ) { 18305 18306 return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); 18307 18308 } 18309 18310 function getNormalIndex( normal ) { 18311 18312 var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); 18313 18314 if ( normalsHash[ hash ] !== undefined ) { 18315 18316 return normalsHash[ hash ]; 18317 18318 } 18319 18320 normalsHash[ hash ] = normals.length / 3; 18321 normals.push( normal.x, normal.y, normal.z ); 18322 18323 return normalsHash[ hash ]; 18324 18325 } 18326 18327 function getColorIndex( color ) { 18328 18329 var hash = color.r.toString() + color.g.toString() + color.b.toString(); 18330 18331 if ( colorsHash[ hash ] !== undefined ) { 18332 18333 return colorsHash[ hash ]; 18334 18335 } 18336 18337 colorsHash[ hash ] = colors.length; 18338 colors.push( color.getHex() ); 18339 18340 return colorsHash[ hash ]; 18341 18342 } 18343 18344 function getUvIndex( uv ) { 18345 18346 var hash = uv.x.toString() + uv.y.toString(); 18347 18348 if ( uvsHash[ hash ] !== undefined ) { 18349 18350 return uvsHash[ hash ]; 18351 18352 } 18353 18354 uvsHash[ hash ] = uvs.length / 2; 18355 uvs.push( uv.x, uv.y ); 18356 18357 return uvsHash[ hash ]; 18358 18359 } 18360 18361 data.data = {}; 18362 18363 data.data.vertices = vertices; 18364 data.data.normals = normals; 18365 if ( colors.length > 0 ) data.data.colors = colors; 18366 if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility 18367 data.data.faces = faces; 18368 18369 return data; 18370 18371 }, 18372 18373 clone: function () { 18374 18375 /* 18376 // Handle primitives 18377 18378 var parameters = this.parameters; 18379 18380 if ( parameters !== undefined ) { 18381 18382 var values = []; 18383 18384 for ( var key in parameters ) { 18385 18386 values.push( parameters[ key ] ); 18387 18388 } 18389 18390 var geometry = Object.create( this.constructor.prototype ); 18391 this.constructor.apply( geometry, values ); 18392 return geometry; 18393 18394 } 18395 18396 return new this.constructor().copy( this ); 18397 */ 18398 18399 return new Geometry().copy( this ); 18400 18401 }, 18402 18403 copy: function ( source ) { 18404 18405 var i, il, j, jl, k, kl; 18406 18407 // reset 18408 18409 this.vertices = []; 18410 this.colors = []; 18411 this.faces = []; 18412 this.faceVertexUvs = [[]]; 18413 this.morphTargets = []; 18414 this.morphNormals = []; 18415 this.skinWeights = []; 18416 this.skinIndices = []; 18417 this.lineDistances = []; 18418 this.boundingBox = null; 18419 this.boundingSphere = null; 18420 18421 // name 18422 18423 this.name = source.name; 18424 18425 // vertices 18426 18427 var vertices = source.vertices; 18428 18429 for ( i = 0, il = vertices.length; i < il; i ++ ) { 18430 18431 this.vertices.push( vertices[ i ].clone() ); 18432 18433 } 18434 18435 // colors 18436 18437 var colors = source.colors; 18438 18439 for ( i = 0, il = colors.length; i < il; i ++ ) { 18440 18441 this.colors.push( colors[ i ].clone() ); 18442 18443 } 18444 18445 // faces 18446 18447 var faces = source.faces; 18448 18449 for ( i = 0, il = faces.length; i < il; i ++ ) { 18450 18451 this.faces.push( faces[ i ].clone() ); 18452 18453 } 18454 18455 // face vertex uvs 18456 18457 for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { 18458 18459 var faceVertexUvs = source.faceVertexUvs[ i ]; 18460 18461 if ( this.faceVertexUvs[ i ] === undefined ) { 18462 18463 this.faceVertexUvs[ i ] = []; 18464 18465 } 18466 18467 for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { 18468 18469 var uvs = faceVertexUvs[ j ], uvsCopy = []; 18470 18471 for ( k = 0, kl = uvs.length; k < kl; k ++ ) { 18472 18473 var uv = uvs[ k ]; 18474 18475 uvsCopy.push( uv.clone() ); 18476 18477 } 18478 18479 this.faceVertexUvs[ i ].push( uvsCopy ); 18480 18481 } 18482 18483 } 18484 18485 // morph targets 18486 18487 var morphTargets = source.morphTargets; 18488 18489 for ( i = 0, il = morphTargets.length; i < il; i ++ ) { 18490 18491 var morphTarget = {}; 18492 morphTarget.name = morphTargets[ i ].name; 18493 18494 // vertices 18495 18496 if ( morphTargets[ i ].vertices !== undefined ) { 18497 18498 morphTarget.vertices = []; 18499 18500 for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { 18501 18502 morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); 18503 18504 } 18505 18506 } 18507 18508 // normals 18509 18510 if ( morphTargets[ i ].normals !== undefined ) { 18511 18512 morphTarget.normals = []; 18513 18514 for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { 18515 18516 morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); 18517 18518 } 18519 18520 } 18521 18522 this.morphTargets.push( morphTarget ); 18523 18524 } 18525 18526 // morph normals 18527 18528 var morphNormals = source.morphNormals; 18529 18530 for ( i = 0, il = morphNormals.length; i < il; i ++ ) { 18531 18532 var morphNormal = {}; 18533 18534 // vertex normals 18535 18536 if ( morphNormals[ i ].vertexNormals !== undefined ) { 18537 18538 morphNormal.vertexNormals = []; 18539 18540 for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { 18541 18542 var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; 18543 var destVertexNormal = {}; 18544 18545 destVertexNormal.a = srcVertexNormal.a.clone(); 18546 destVertexNormal.b = srcVertexNormal.b.clone(); 18547 destVertexNormal.c = srcVertexNormal.c.clone(); 18548 18549 morphNormal.vertexNormals.push( destVertexNormal ); 18550 18551 } 18552 18553 } 18554 18555 // face normals 18556 18557 if ( morphNormals[ i ].faceNormals !== undefined ) { 18558 18559 morphNormal.faceNormals = []; 18560 18561 for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { 18562 18563 morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); 18564 18565 } 18566 18567 } 18568 18569 this.morphNormals.push( morphNormal ); 18570 18571 } 18572 18573 // skin weights 18574 18575 var skinWeights = source.skinWeights; 18576 18577 for ( i = 0, il = skinWeights.length; i < il; i ++ ) { 18578 18579 this.skinWeights.push( skinWeights[ i ].clone() ); 18580 18581 } 18582 18583 // skin indices 18584 18585 var skinIndices = source.skinIndices; 18586 18587 for ( i = 0, il = skinIndices.length; i < il; i ++ ) { 18588 18589 this.skinIndices.push( skinIndices[ i ].clone() ); 18590 18591 } 18592 18593 // line distances 18594 18595 var lineDistances = source.lineDistances; 18596 18597 for ( i = 0, il = lineDistances.length; i < il; i ++ ) { 18598 18599 this.lineDistances.push( lineDistances[ i ] ); 18600 18601 } 18602 18603 // bounding box 18604 18605 var boundingBox = source.boundingBox; 18606 18607 if ( boundingBox !== null ) { 18608 18609 this.boundingBox = boundingBox.clone(); 18610 18611 } 18612 18613 // bounding sphere 18614 18615 var boundingSphere = source.boundingSphere; 18616 18617 if ( boundingSphere !== null ) { 18618 18619 this.boundingSphere = boundingSphere.clone(); 18620 18621 } 18622 18623 // update flags 18624 18625 this.elementsNeedUpdate = source.elementsNeedUpdate; 18626 this.verticesNeedUpdate = source.verticesNeedUpdate; 18627 this.uvsNeedUpdate = source.uvsNeedUpdate; 18628 this.normalsNeedUpdate = source.normalsNeedUpdate; 18629 this.colorsNeedUpdate = source.colorsNeedUpdate; 18630 this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; 18631 this.groupsNeedUpdate = source.groupsNeedUpdate; 18632 18633 return this; 18634 18635 }, 18636 18637 dispose: function () { 18638 18639 this.dispatchEvent( { type: 'dispose' } ); 18640 18641 } 18642 18643 } ); 18644 18645 /** 18646 * @author mrdoob / http://mrdoob.com/ 18647 */ 18648 18649 function BufferAttribute( array, itemSize, normalized ) { 18650 18651 if ( Array.isArray( array ) ) { 18652 18653 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); 18654 18655 } 18656 18657 this.name = ''; 18658 18659 this.array = array; 18660 this.itemSize = itemSize; 18661 this.count = array !== undefined ? array.length / itemSize : 0; 18662 this.normalized = normalized === true; 18663 18664 this.dynamic = false; 18665 this.updateRange = { offset: 0, count: - 1 }; 18666 18667 this.version = 0; 18668 18669 } 18670 18671 Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { 18672 18673 set: function ( value ) { 18674 18675 if ( value === true ) this.version ++; 18676 18677 } 18678 18679 } ); 18680 18681 Object.assign( BufferAttribute.prototype, { 18682 18683 isBufferAttribute: true, 18684 18685 onUploadCallback: function () {}, 18686 18687 setArray: function ( array ) { 18688 18689 if ( Array.isArray( array ) ) { 18690 18691 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); 18692 18693 } 18694 18695 this.count = array !== undefined ? array.length / this.itemSize : 0; 18696 this.array = array; 18697 18698 return this; 18699 18700 }, 18701 18702 setDynamic: function ( value ) { 18703 18704 this.dynamic = value; 18705 18706 return this; 18707 18708 }, 18709 18710 copy: function ( source ) { 18711 18712 this.name = source.name; 18713 this.array = new source.array.constructor( source.array ); 18714 this.itemSize = source.itemSize; 18715 this.count = source.count; 18716 this.normalized = source.normalized; 18717 18718 this.dynamic = source.dynamic; 18719 18720 return this; 18721 18722 }, 18723 18724 copyAt: function ( index1, attribute, index2 ) { 18725 18726 index1 *= this.itemSize; 18727 index2 *= attribute.itemSize; 18728 18729 for ( var i = 0, l = this.itemSize; i < l; i ++ ) { 18730 18731 this.array[ index1 + i ] = attribute.array[ index2 + i ]; 18732 18733 } 18734 18735 return this; 18736 18737 }, 18738 18739 copyArray: function ( array ) { 18740 18741 this.array.set( array ); 18742 18743 return this; 18744 18745 }, 18746 18747 copyColorsArray: function ( colors ) { 18748 18749 var array = this.array, offset = 0; 18750 18751 for ( var i = 0, l = colors.length; i < l; i ++ ) { 18752 18753 var color = colors[ i ]; 18754 18755 if ( color === undefined ) { 18756 18757 console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); 18758 color = new Color(); 18759 18760 } 18761 18762 array[ offset ++ ] = color.r; 18763 array[ offset ++ ] = color.g; 18764 array[ offset ++ ] = color.b; 18765 18766 } 18767 18768 return this; 18769 18770 }, 18771 18772 copyVector2sArray: function ( vectors ) { 18773 18774 var array = this.array, offset = 0; 18775 18776 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 18777 18778 var vector = vectors[ i ]; 18779 18780 if ( vector === undefined ) { 18781 18782 console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); 18783 vector = new Vector2(); 18784 18785 } 18786 18787 array[ offset ++ ] = vector.x; 18788 array[ offset ++ ] = vector.y; 18789 18790 } 18791 18792 return this; 18793 18794 }, 18795 18796 copyVector3sArray: function ( vectors ) { 18797 18798 var array = this.array, offset = 0; 18799 18800 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 18801 18802 var vector = vectors[ i ]; 18803 18804 if ( vector === undefined ) { 18805 18806 console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); 18807 vector = new Vector3(); 18808 18809 } 18810 18811 array[ offset ++ ] = vector.x; 18812 array[ offset ++ ] = vector.y; 18813 array[ offset ++ ] = vector.z; 18814 18815 } 18816 18817 return this; 18818 18819 }, 18820 18821 copyVector4sArray: function ( vectors ) { 18822 18823 var array = this.array, offset = 0; 18824 18825 for ( var i = 0, l = vectors.length; i < l; i ++ ) { 18826 18827 var vector = vectors[ i ]; 18828 18829 if ( vector === undefined ) { 18830 18831 console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); 18832 vector = new Vector4(); 18833 18834 } 18835 18836 array[ offset ++ ] = vector.x; 18837 array[ offset ++ ] = vector.y; 18838 array[ offset ++ ] = vector.z; 18839 array[ offset ++ ] = vector.w; 18840 18841 } 18842 18843 return this; 18844 18845 }, 18846 18847 set: function ( value, offset ) { 18848 18849 if ( offset === undefined ) offset = 0; 18850 18851 this.array.set( value, offset ); 18852 18853 return this; 18854 18855 }, 18856 18857 getX: function ( index ) { 18858 18859 return this.array[ index * this.itemSize ]; 18860 18861 }, 18862 18863 setX: function ( index, x ) { 18864 18865 this.array[ index * this.itemSize ] = x; 18866 18867 return this; 18868 18869 }, 18870 18871 getY: function ( index ) { 18872 18873 return this.array[ index * this.itemSize + 1 ]; 18874 18875 }, 18876 18877 setY: function ( index, y ) { 18878 18879 this.array[ index * this.itemSize + 1 ] = y; 18880 18881 return this; 18882 18883 }, 18884 18885 getZ: function ( index ) { 18886 18887 return this.array[ index * this.itemSize + 2 ]; 18888 18889 }, 18890 18891 setZ: function ( index, z ) { 18892 18893 this.array[ index * this.itemSize + 2 ] = z; 18894 18895 return this; 18896 18897 }, 18898 18899 getW: function ( index ) { 18900 18901 return this.array[ index * this.itemSize + 3 ]; 18902 18903 }, 18904 18905 setW: function ( index, w ) { 18906 18907 this.array[ index * this.itemSize + 3 ] = w; 18908 18909 return this; 18910 18911 }, 18912 18913 setXY: function ( index, x, y ) { 18914 18915 index *= this.itemSize; 18916 18917 this.array[ index + 0 ] = x; 18918 this.array[ index + 1 ] = y; 18919 18920 return this; 18921 18922 }, 18923 18924 setXYZ: function ( index, x, y, z ) { 18925 18926 index *= this.itemSize; 18927 18928 this.array[ index + 0 ] = x; 18929 this.array[ index + 1 ] = y; 18930 this.array[ index + 2 ] = z; 18931 18932 return this; 18933 18934 }, 18935 18936 setXYZW: function ( index, x, y, z, w ) { 18937 18938 index *= this.itemSize; 18939 18940 this.array[ index + 0 ] = x; 18941 this.array[ index + 1 ] = y; 18942 this.array[ index + 2 ] = z; 18943 this.array[ index + 3 ] = w; 18944 18945 return this; 18946 18947 }, 18948 18949 onUpload: function ( callback ) { 18950 18951 this.onUploadCallback = callback; 18952 18953 return this; 18954 18955 }, 18956 18957 clone: function () { 18958 18959 return new this.constructor( this.array, this.itemSize ).copy( this ); 18960 18961 } 18962 18963 } ); 18964 18965 // 18966 18967 function Int8BufferAttribute( array, itemSize, normalized ) { 18968 18969 BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); 18970 18971 } 18972 18973 Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 18974 Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; 18975 18976 18977 function Uint8BufferAttribute( array, itemSize, normalized ) { 18978 18979 BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); 18980 18981 } 18982 18983 Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 18984 Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; 18985 18986 18987 function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { 18988 18989 BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); 18990 18991 } 18992 18993 Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 18994 Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; 18995 18996 18997 function Int16BufferAttribute( array, itemSize, normalized ) { 18998 18999 BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); 19000 19001 } 19002 19003 Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19004 Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; 19005 19006 19007 function Uint16BufferAttribute( array, itemSize, normalized ) { 19008 19009 BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); 19010 19011 } 19012 19013 Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19014 Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; 19015 19016 19017 function Int32BufferAttribute( array, itemSize, normalized ) { 19018 19019 BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); 19020 19021 } 19022 19023 Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19024 Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; 19025 19026 19027 function Uint32BufferAttribute( array, itemSize, normalized ) { 19028 19029 BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); 19030 19031 } 19032 19033 Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19034 Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; 19035 19036 19037 function Float32BufferAttribute( array, itemSize, normalized ) { 19038 19039 BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); 19040 19041 } 19042 19043 Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19044 Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; 19045 19046 19047 function Float64BufferAttribute( array, itemSize, normalized ) { 19048 19049 BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); 19050 19051 } 19052 19053 Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); 19054 Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; 19055 19056 /** 19057 * @author mrdoob / http://mrdoob.com/ 19058 */ 19059 19060 function DirectGeometry() { 19061 19062 this.vertices = []; 19063 this.normals = []; 19064 this.colors = []; 19065 this.uvs = []; 19066 this.uvs2 = []; 19067 19068 this.groups = []; 19069 19070 this.morphTargets = {}; 19071 19072 this.skinWeights = []; 19073 this.skinIndices = []; 19074 19075 // this.lineDistances = []; 19076 19077 this.boundingBox = null; 19078 this.boundingSphere = null; 19079 19080 // update flags 19081 19082 this.verticesNeedUpdate = false; 19083 this.normalsNeedUpdate = false; 19084 this.colorsNeedUpdate = false; 19085 this.uvsNeedUpdate = false; 19086 this.groupsNeedUpdate = false; 19087 19088 } 19089 19090 Object.assign( DirectGeometry.prototype, { 19091 19092 computeGroups: function ( geometry ) { 19093 19094 var group; 19095 var groups = []; 19096 var materialIndex = undefined; 19097 19098 var faces = geometry.faces; 19099 19100 for ( var i = 0; i < faces.length; i ++ ) { 19101 19102 var face = faces[ i ]; 19103 19104 // materials 19105 19106 if ( face.materialIndex !== materialIndex ) { 19107 19108 materialIndex = face.materialIndex; 19109 19110 if ( group !== undefined ) { 19111 19112 group.count = ( i * 3 ) - group.start; 19113 groups.push( group ); 19114 19115 } 19116 19117 group = { 19118 start: i * 3, 19119 materialIndex: materialIndex 19120 }; 19121 19122 } 19123 19124 } 19125 19126 if ( group !== undefined ) { 19127 19128 group.count = ( i * 3 ) - group.start; 19129 groups.push( group ); 19130 19131 } 19132 19133 this.groups = groups; 19134 19135 }, 19136 19137 fromGeometry: function ( geometry ) { 19138 19139 var faces = geometry.faces; 19140 var vertices = geometry.vertices; 19141 var faceVertexUvs = geometry.faceVertexUvs; 19142 19143 var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; 19144 var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; 19145 19146 // morphs 19147 19148 var morphTargets = geometry.morphTargets; 19149 var morphTargetsLength = morphTargets.length; 19150 19151 var morphTargetsPosition; 19152 19153 if ( morphTargetsLength > 0 ) { 19154 19155 morphTargetsPosition = []; 19156 19157 for ( var i = 0; i < morphTargetsLength; i ++ ) { 19158 19159 morphTargetsPosition[ i ] = []; 19160 19161 } 19162 19163 this.morphTargets.position = morphTargetsPosition; 19164 19165 } 19166 19167 var morphNormals = geometry.morphNormals; 19168 var morphNormalsLength = morphNormals.length; 19169 19170 var morphTargetsNormal; 19171 19172 if ( morphNormalsLength > 0 ) { 19173 19174 morphTargetsNormal = []; 19175 19176 for ( var i = 0; i < morphNormalsLength; i ++ ) { 19177 19178 morphTargetsNormal[ i ] = []; 19179 19180 } 19181 19182 this.morphTargets.normal = morphTargetsNormal; 19183 19184 } 19185 19186 // skins 19187 19188 var skinIndices = geometry.skinIndices; 19189 var skinWeights = geometry.skinWeights; 19190 19191 var hasSkinIndices = skinIndices.length === vertices.length; 19192 var hasSkinWeights = skinWeights.length === vertices.length; 19193 19194 // 19195 19196 if ( faces.length === 0 ) { 19197 19198 console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); 19199 19200 } 19201 19202 for ( var i = 0; i < faces.length; i ++ ) { 19203 19204 var face = faces[ i ]; 19205 19206 this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); 19207 19208 var vertexNormals = face.vertexNormals; 19209 19210 if ( vertexNormals.length === 3 ) { 19211 19212 this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); 19213 19214 } else { 19215 19216 var normal = face.normal; 19217 19218 this.normals.push( normal, normal, normal ); 19219 19220 } 19221 19222 var vertexColors = face.vertexColors; 19223 19224 if ( vertexColors.length === 3 ) { 19225 19226 this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); 19227 19228 } else { 19229 19230 var color = face.color; 19231 19232 this.colors.push( color, color, color ); 19233 19234 } 19235 19236 if ( hasFaceVertexUv === true ) { 19237 19238 var vertexUvs = faceVertexUvs[ 0 ][ i ]; 19239 19240 if ( vertexUvs !== undefined ) { 19241 19242 this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); 19243 19244 } else { 19245 19246 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); 19247 19248 this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); 19249 19250 } 19251 19252 } 19253 19254 if ( hasFaceVertexUv2 === true ) { 19255 19256 var vertexUvs = faceVertexUvs[ 1 ][ i ]; 19257 19258 if ( vertexUvs !== undefined ) { 19259 19260 this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); 19261 19262 } else { 19263 19264 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); 19265 19266 this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); 19267 19268 } 19269 19270 } 19271 19272 // morphs 19273 19274 for ( var j = 0; j < morphTargetsLength; j ++ ) { 19275 19276 var morphTarget = morphTargets[ j ].vertices; 19277 19278 morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); 19279 19280 } 19281 19282 for ( var j = 0; j < morphNormalsLength; j ++ ) { 19283 19284 var morphNormal = morphNormals[ j ].vertexNormals[ i ]; 19285 19286 morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c ); 19287 19288 } 19289 19290 // skins 19291 19292 if ( hasSkinIndices ) { 19293 19294 this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); 19295 19296 } 19297 19298 if ( hasSkinWeights ) { 19299 19300 this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); 19301 19302 } 19303 19304 } 19305 19306 this.computeGroups( geometry ); 19307 19308 this.verticesNeedUpdate = geometry.verticesNeedUpdate; 19309 this.normalsNeedUpdate = geometry.normalsNeedUpdate; 19310 this.colorsNeedUpdate = geometry.colorsNeedUpdate; 19311 this.uvsNeedUpdate = geometry.uvsNeedUpdate; 19312 this.groupsNeedUpdate = geometry.groupsNeedUpdate; 19313 19314 return this; 19315 19316 } 19317 19318 } ); 19319 19320 /** 19321 * @author mrdoob / http://mrdoob.com/ 19322 */ 19323 19324 function arrayMax( array ) { 19325 19326 if ( array.length === 0 ) return - Infinity; 19327 19328 var max = array[ 0 ]; 19329 19330 for ( var i = 1, l = array.length; i < l; ++ i ) { 19331 19332 if ( array[ i ] > max ) max = array[ i ]; 19333 19334 } 19335 19336 return max; 19337 19338 } 19339 19340 /** 19341 * @author alteredq / http://alteredqualia.com/ 19342 * @author mrdoob / http://mrdoob.com/ 19343 */ 19344 19345 var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id 19346 19347 function BufferGeometry() { 19348 19349 Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); 19350 19351 this.uuid = _Math.generateUUID(); 19352 19353 this.name = ''; 19354 this.type = 'BufferGeometry'; 19355 19356 this.index = null; 19357 this.attributes = {}; 19358 19359 this.morphAttributes = {}; 19360 19361 this.groups = []; 19362 19363 this.boundingBox = null; 19364 this.boundingSphere = null; 19365 19366 this.drawRange = { start: 0, count: Infinity }; 19367 19368 this.userData = {}; 19369 19370 } 19371 19372 BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 19373 19374 constructor: BufferGeometry, 19375 19376 isBufferGeometry: true, 19377 19378 getIndex: function () { 19379 19380 return this.index; 19381 19382 }, 19383 19384 setIndex: function ( index ) { 19385 19386 if ( Array.isArray( index ) ) { 19387 19388 this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); 19389 19390 } else { 19391 19392 this.index = index; 19393 19394 } 19395 19396 }, 19397 19398 addAttribute: function ( name, attribute ) { 19399 19400 if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { 19401 19402 console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); 19403 19404 return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); 19405 19406 } 19407 19408 if ( name === 'index' ) { 19409 19410 console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); 19411 this.setIndex( attribute ); 19412 19413 return this; 19414 19415 } 19416 19417 this.attributes[ name ] = attribute; 19418 19419 return this; 19420 19421 }, 19422 19423 getAttribute: function ( name ) { 19424 19425 return this.attributes[ name ]; 19426 19427 }, 19428 19429 removeAttribute: function ( name ) { 19430 19431 delete this.attributes[ name ]; 19432 19433 return this; 19434 19435 }, 19436 19437 addGroup: function ( start, count, materialIndex ) { 19438 19439 this.groups.push( { 19440 19441 start: start, 19442 count: count, 19443 materialIndex: materialIndex !== undefined ? materialIndex : 0 19444 19445 } ); 19446 19447 }, 19448 19449 clearGroups: function () { 19450 19451 this.groups = []; 19452 19453 }, 19454 19455 setDrawRange: function ( start, count ) { 19456 19457 this.drawRange.start = start; 19458 this.drawRange.count = count; 19459 19460 }, 19461 19462 applyMatrix: function ( matrix ) { 19463 19464 var position = this.attributes.position; 19465 19466 if ( position !== undefined ) { 19467 19468 matrix.applyToBufferAttribute( position ); 19469 position.needsUpdate = true; 19470 19471 } 19472 19473 var normal = this.attributes.normal; 19474 19475 if ( normal !== undefined ) { 19476 19477 var normalMatrix = new Matrix3().getNormalMatrix( matrix ); 19478 19479 normalMatrix.applyToBufferAttribute( normal ); 19480 normal.needsUpdate = true; 19481 19482 } 19483 19484 if ( this.boundingBox !== null ) { 19485 19486 this.computeBoundingBox(); 19487 19488 } 19489 19490 if ( this.boundingSphere !== null ) { 19491 19492 this.computeBoundingSphere(); 19493 19494 } 19495 19496 return this; 19497 19498 }, 19499 19500 rotateX: function () { 19501 19502 // rotate geometry around world x-axis 19503 19504 var m1 = new Matrix4(); 19505 19506 return function rotateX( angle ) { 19507 19508 m1.makeRotationX( angle ); 19509 19510 this.applyMatrix( m1 ); 19511 19512 return this; 19513 19514 }; 19515 19516 }(), 19517 19518 rotateY: function () { 19519 19520 // rotate geometry around world y-axis 19521 19522 var m1 = new Matrix4(); 19523 19524 return function rotateY( angle ) { 19525 19526 m1.makeRotationY( angle ); 19527 19528 this.applyMatrix( m1 ); 19529 19530 return this; 19531 19532 }; 19533 19534 }(), 19535 19536 rotateZ: function () { 19537 19538 // rotate geometry around world z-axis 19539 19540 var m1 = new Matrix4(); 19541 19542 return function rotateZ( angle ) { 19543 19544 m1.makeRotationZ( angle ); 19545 19546 this.applyMatrix( m1 ); 19547 19548 return this; 19549 19550 }; 19551 19552 }(), 19553 19554 translate: function () { 19555 19556 // translate geometry 19557 19558 var m1 = new Matrix4(); 19559 19560 return function translate( x, y, z ) { 19561 19562 m1.makeTranslation( x, y, z ); 19563 19564 this.applyMatrix( m1 ); 19565 19566 return this; 19567 19568 }; 19569 19570 }(), 19571 19572 scale: function () { 19573 19574 // scale geometry 19575 19576 var m1 = new Matrix4(); 19577 19578 return function scale( x, y, z ) { 19579 19580 m1.makeScale( x, y, z ); 19581 19582 this.applyMatrix( m1 ); 19583 19584 return this; 19585 19586 }; 19587 19588 }(), 19589 19590 lookAt: function () { 19591 19592 var obj = new Object3D(); 19593 19594 return function lookAt( vector ) { 19595 19596 obj.lookAt( vector ); 19597 19598 obj.updateMatrix(); 19599 19600 this.applyMatrix( obj.matrix ); 19601 19602 }; 19603 19604 }(), 19605 19606 center: function () { 19607 19608 var offset = new Vector3(); 19609 19610 return function center() { 19611 19612 this.computeBoundingBox(); 19613 19614 this.boundingBox.getCenter( offset ).negate(); 19615 19616 this.translate( offset.x, offset.y, offset.z ); 19617 19618 return this; 19619 19620 }; 19621 19622 }(), 19623 19624 setFromObject: function ( object ) { 19625 19626 // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); 19627 19628 var geometry = object.geometry; 19629 19630 if ( object.isPoints || object.isLine ) { 19631 19632 var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); 19633 var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); 19634 19635 this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); 19636 this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); 19637 19638 if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { 19639 19640 var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); 19641 19642 this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); 19643 19644 } 19645 19646 if ( geometry.boundingSphere !== null ) { 19647 19648 this.boundingSphere = geometry.boundingSphere.clone(); 19649 19650 } 19651 19652 if ( geometry.boundingBox !== null ) { 19653 19654 this.boundingBox = geometry.boundingBox.clone(); 19655 19656 } 19657 19658 } else if ( object.isMesh ) { 19659 19660 if ( geometry && geometry.isGeometry ) { 19661 19662 this.fromGeometry( geometry ); 19663 19664 } 19665 19666 } 19667 19668 return this; 19669 19670 }, 19671 19672 setFromPoints: function ( points ) { 19673 19674 var position = []; 19675 19676 for ( var i = 0, l = points.length; i < l; i ++ ) { 19677 19678 var point = points[ i ]; 19679 position.push( point.x, point.y, point.z || 0 ); 19680 19681 } 19682 19683 this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); 19684 19685 return this; 19686 19687 }, 19688 19689 updateFromObject: function ( object ) { 19690 19691 var geometry = object.geometry; 19692 19693 if ( object.isMesh ) { 19694 19695 var direct = geometry.__directGeometry; 19696 19697 if ( geometry.elementsNeedUpdate === true ) { 19698 19699 direct = undefined; 19700 geometry.elementsNeedUpdate = false; 19701 19702 } 19703 19704 if ( direct === undefined ) { 19705 19706 return this.fromGeometry( geometry ); 19707 19708 } 19709 19710 direct.verticesNeedUpdate = geometry.verticesNeedUpdate; 19711 direct.normalsNeedUpdate = geometry.normalsNeedUpdate; 19712 direct.colorsNeedUpdate = geometry.colorsNeedUpdate; 19713 direct.uvsNeedUpdate = geometry.uvsNeedUpdate; 19714 direct.groupsNeedUpdate = geometry.groupsNeedUpdate; 19715 19716 geometry.verticesNeedUpdate = false; 19717 geometry.normalsNeedUpdate = false; 19718 geometry.colorsNeedUpdate = false; 19719 geometry.uvsNeedUpdate = false; 19720 geometry.groupsNeedUpdate = false; 19721 19722 geometry = direct; 19723 19724 } 19725 19726 var attribute; 19727 19728 if ( geometry.verticesNeedUpdate === true ) { 19729 19730 attribute = this.attributes.position; 19731 19732 if ( attribute !== undefined ) { 19733 19734 attribute.copyVector3sArray( geometry.vertices ); 19735 attribute.needsUpdate = true; 19736 19737 } 19738 19739 geometry.verticesNeedUpdate = false; 19740 19741 } 19742 19743 if ( geometry.normalsNeedUpdate === true ) { 19744 19745 attribute = this.attributes.normal; 19746 19747 if ( attribute !== undefined ) { 19748 19749 attribute.copyVector3sArray( geometry.normals ); 19750 attribute.needsUpdate = true; 19751 19752 } 19753 19754 geometry.normalsNeedUpdate = false; 19755 19756 } 19757 19758 if ( geometry.colorsNeedUpdate === true ) { 19759 19760 attribute = this.attributes.color; 19761 19762 if ( attribute !== undefined ) { 19763 19764 attribute.copyColorsArray( geometry.colors ); 19765 attribute.needsUpdate = true; 19766 19767 } 19768 19769 geometry.colorsNeedUpdate = false; 19770 19771 } 19772 19773 if ( geometry.uvsNeedUpdate ) { 19774 19775 attribute = this.attributes.uv; 19776 19777 if ( attribute !== undefined ) { 19778 19779 attribute.copyVector2sArray( geometry.uvs ); 19780 attribute.needsUpdate = true; 19781 19782 } 19783 19784 geometry.uvsNeedUpdate = false; 19785 19786 } 19787 19788 if ( geometry.lineDistancesNeedUpdate ) { 19789 19790 attribute = this.attributes.lineDistance; 19791 19792 if ( attribute !== undefined ) { 19793 19794 attribute.copyArray( geometry.lineDistances ); 19795 attribute.needsUpdate = true; 19796 19797 } 19798 19799 geometry.lineDistancesNeedUpdate = false; 19800 19801 } 19802 19803 if ( geometry.groupsNeedUpdate ) { 19804 19805 geometry.computeGroups( object.geometry ); 19806 this.groups = geometry.groups; 19807 19808 geometry.groupsNeedUpdate = false; 19809 19810 } 19811 19812 return this; 19813 19814 }, 19815 19816 fromGeometry: function ( geometry ) { 19817 19818 geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); 19819 19820 return this.fromDirectGeometry( geometry.__directGeometry ); 19821 19822 }, 19823 19824 fromDirectGeometry: function ( geometry ) { 19825 19826 var positions = new Float32Array( geometry.vertices.length * 3 ); 19827 this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); 19828 19829 if ( geometry.normals.length > 0 ) { 19830 19831 var normals = new Float32Array( geometry.normals.length * 3 ); 19832 this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); 19833 19834 } 19835 19836 if ( geometry.colors.length > 0 ) { 19837 19838 var colors = new Float32Array( geometry.colors.length * 3 ); 19839 this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); 19840 19841 } 19842 19843 if ( geometry.uvs.length > 0 ) { 19844 19845 var uvs = new Float32Array( geometry.uvs.length * 2 ); 19846 this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); 19847 19848 } 19849 19850 if ( geometry.uvs2.length > 0 ) { 19851 19852 var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); 19853 this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); 19854 19855 } 19856 19857 // groups 19858 19859 this.groups = geometry.groups; 19860 19861 // morphs 19862 19863 for ( var name in geometry.morphTargets ) { 19864 19865 var array = []; 19866 var morphTargets = geometry.morphTargets[ name ]; 19867 19868 for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { 19869 19870 var morphTarget = morphTargets[ i ]; 19871 19872 var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 ); 19873 19874 array.push( attribute.copyVector3sArray( morphTarget ) ); 19875 19876 } 19877 19878 this.morphAttributes[ name ] = array; 19879 19880 } 19881 19882 // skinning 19883 19884 if ( geometry.skinIndices.length > 0 ) { 19885 19886 var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); 19887 this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); 19888 19889 } 19890 19891 if ( geometry.skinWeights.length > 0 ) { 19892 19893 var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); 19894 this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); 19895 19896 } 19897 19898 // 19899 19900 if ( geometry.boundingSphere !== null ) { 19901 19902 this.boundingSphere = geometry.boundingSphere.clone(); 19903 19904 } 19905 19906 if ( geometry.boundingBox !== null ) { 19907 19908 this.boundingBox = geometry.boundingBox.clone(); 19909 19910 } 19911 19912 return this; 19913 19914 }, 19915 19916 computeBoundingBox: function () { 19917 19918 if ( this.boundingBox === null ) { 19919 19920 this.boundingBox = new Box3(); 19921 19922 } 19923 19924 var position = this.attributes.position; 19925 19926 if ( position !== undefined ) { 19927 19928 this.boundingBox.setFromBufferAttribute( position ); 19929 19930 } else { 19931 19932 this.boundingBox.makeEmpty(); 19933 19934 } 19935 19936 if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { 19937 19938 console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); 19939 19940 } 19941 19942 }, 19943 19944 computeBoundingSphere: function () { 19945 19946 var box = new Box3(); 19947 var vector = new Vector3(); 19948 19949 return function computeBoundingSphere() { 19950 19951 if ( this.boundingSphere === null ) { 19952 19953 this.boundingSphere = new Sphere(); 19954 19955 } 19956 19957 var position = this.attributes.position; 19958 19959 if ( position ) { 19960 19961 var center = this.boundingSphere.center; 19962 19963 box.setFromBufferAttribute( position ); 19964 box.getCenter( center ); 19965 19966 // hoping to find a boundingSphere with a radius smaller than the 19967 // boundingSphere of the boundingBox: sqrt(3) smaller in the best case 19968 19969 var maxRadiusSq = 0; 19970 19971 for ( var i = 0, il = position.count; i < il; i ++ ) { 19972 19973 vector.x = position.getX( i ); 19974 vector.y = position.getY( i ); 19975 vector.z = position.getZ( i ); 19976 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); 19977 19978 } 19979 19980 this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); 19981 19982 if ( isNaN( this.boundingSphere.radius ) ) { 19983 19984 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); 19985 19986 } 19987 19988 } 19989 19990 }; 19991 19992 }(), 19993 19994 computeFaceNormals: function () { 19995 19996 // backwards compatibility 19997 19998 }, 19999 20000 computeVertexNormals: function () { 20001 20002 var index = this.index; 20003 var attributes = this.attributes; 20004 var groups = this.groups; 20005 20006 if ( attributes.position ) { 20007 20008 var positions = attributes.position.array; 20009 20010 if ( attributes.normal === undefined ) { 20011 20012 this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); 20013 20014 } else { 20015 20016 // reset existing normals to zero 20017 20018 var array = attributes.normal.array; 20019 20020 for ( var i = 0, il = array.length; i < il; i ++ ) { 20021 20022 array[ i ] = 0; 20023 20024 } 20025 20026 } 20027 20028 var normals = attributes.normal.array; 20029 20030 var vA, vB, vC; 20031 var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); 20032 var cb = new Vector3(), ab = new Vector3(); 20033 20034 // indexed elements 20035 20036 if ( index ) { 20037 20038 var indices = index.array; 20039 20040 if ( groups.length === 0 ) { 20041 20042 this.addGroup( 0, indices.length ); 20043 20044 } 20045 20046 for ( var j = 0, jl = groups.length; j < jl; ++ j ) { 20047 20048 var group = groups[ j ]; 20049 20050 var start = group.start; 20051 var count = group.count; 20052 20053 for ( var i = start, il = start + count; i < il; i += 3 ) { 20054 20055 vA = indices[ i + 0 ] * 3; 20056 vB = indices[ i + 1 ] * 3; 20057 vC = indices[ i + 2 ] * 3; 20058 20059 pA.fromArray( positions, vA ); 20060 pB.fromArray( positions, vB ); 20061 pC.fromArray( positions, vC ); 20062 20063 cb.subVectors( pC, pB ); 20064 ab.subVectors( pA, pB ); 20065 cb.cross( ab ); 20066 20067 normals[ vA ] += cb.x; 20068 normals[ vA + 1 ] += cb.y; 20069 normals[ vA + 2 ] += cb.z; 20070 20071 normals[ vB ] += cb.x; 20072 normals[ vB + 1 ] += cb.y; 20073 normals[ vB + 2 ] += cb.z; 20074 20075 normals[ vC ] += cb.x; 20076 normals[ vC + 1 ] += cb.y; 20077 normals[ vC + 2 ] += cb.z; 20078 20079 } 20080 20081 } 20082 20083 } else { 20084 20085 // non-indexed elements (unconnected triangle soup) 20086 20087 for ( var i = 0, il = positions.length; i < il; i += 9 ) { 20088 20089 pA.fromArray( positions, i ); 20090 pB.fromArray( positions, i + 3 ); 20091 pC.fromArray( positions, i + 6 ); 20092 20093 cb.subVectors( pC, pB ); 20094 ab.subVectors( pA, pB ); 20095 cb.cross( ab ); 20096 20097 normals[ i ] = cb.x; 20098 normals[ i + 1 ] = cb.y; 20099 normals[ i + 2 ] = cb.z; 20100 20101 normals[ i + 3 ] = cb.x; 20102 normals[ i + 4 ] = cb.y; 20103 normals[ i + 5 ] = cb.z; 20104 20105 normals[ i + 6 ] = cb.x; 20106 normals[ i + 7 ] = cb.y; 20107 normals[ i + 8 ] = cb.z; 20108 20109 } 20110 20111 } 20112 20113 this.normalizeNormals(); 20114 20115 attributes.normal.needsUpdate = true; 20116 20117 } 20118 20119 }, 20120
20121 merge: function ( geometry, offset ) { 20122 20123 if ( ! ( geometry && geometry.isBufferGeometry ) ) { 20124 20125 console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); 20126 return; 20127 20128 } 20129 20130 if ( offset === undefined ) { 20131 20132 offset = 0; 20133 20134 console.warn( 20135 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' 20136 + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' 20137 ); 20138 20139 } 20140 20141 var attributes = this.attributes; 20142 20143 for ( var key in attributes ) { 20144 20145 if ( geometry.attributes[ key ] === undefined ) continue; 20146 20147 var attribute1 = attributes[ key ]; 20148 var attributeArray1 = attribute1.array; 20149 20150 var attribute2 = geometry.attributes[ key ]; 20151 var attributeArray2 = attribute2.array; 20152 20153 var attributeSize = attribute2.itemSize; 20154 20155 for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) { 20156 20157 attributeArray1[ j ] = attributeArray2[ i ]; 20158 20159 } 20160 20161 } 20162 20163 return this; 20164 20165 }, 20166 20167 normalizeNormals: function () { 20168 20169 var vector = new Vector3(); 20170 20171 return function normalizeNormals() { 20172 20173 var normals = this.attributes.normal; 20174 20175 for ( var i = 0, il = normals.count; i < il; i ++ ) { 20176 20177 vector.x = normals.getX( i ); 20178 vector.y = normals.getY( i ); 20179 vector.z = normals.getZ( i ); 20180 20181 vector.normalize(); 20182 20183 normals.setXYZ( i, vector.x, vector.y, vector.z ); 20184 20185 } 20186 20187 }; 20188 20189 }(), 20190 20191 toNonIndexed: function () { 20192 20193 if ( this.index === null ) { 20194 20195 console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); 20196 return this; 20197 20198 } 20199 20200 var geometry2 = new BufferGeometry(); 20201 20202 var indices = this.index.array; 20203 var attributes = this.attributes; 20204 20205 for ( var name in attributes ) { 20206 20207 var attribute = attributes[ name ]; 20208 20209 var array = attribute.array; 20210 var itemSize = attribute.itemSize; 20211 20212 var array2 = new array.constructor( indices.length * itemSize ); 20213 20214 var index = 0, index2 = 0; 20215 20216 for ( var i = 0, l = indices.length; i < l; i ++ ) { 20217 20218 index = indices[ i ] * itemSize; 20219 20220 for ( var j = 0; j < itemSize; j ++ ) { 20221 20222 array2[ index2 ++ ] = array[ index ++ ]; 20223 20224 } 20225 20226 } 20227 20228 geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) ); 20229 20230 } 20231 20232 var groups = this.groups; 20233 20234 for ( var i = 0, l = groups.length; i < l; i ++ ) { 20235 20236 var group = groups[ i ]; 20237 geometry2.addGroup( group.start, group.count, group.materialIndex ); 20238 20239 } 20240 20241 return geometry2; 20242 20243 }, 20244 20245 toJSON: function () { 20246 20247 var data = { 20248 metadata: { 20249 version: 4.5, 20250 type: 'BufferGeometry', 20251 generator: 'BufferGeometry.toJSON' 20252 } 20253 }; 20254 20255 // standard BufferGeometry serialization 20256 20257 data.uuid = this.uuid; 20258 data.type = this.type; 20259 if ( this.name !== '' ) data.name = this.name; 20260 if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; 20261 20262 if ( this.parameters !== undefined ) { 20263 20264 var parameters = this.parameters; 20265 20266 for ( var key in parameters ) { 20267 20268 if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; 20269 20270 } 20271 20272 return data; 20273 20274 } 20275 20276 data.data = { attributes: {} }; 20277 20278 var index = this.index; 20279 20280 if ( index !== null ) { 20281 20282 var array = Array.prototype.slice.call( index.array ); 20283 20284 data.data.index = { 20285 type: index.array.constructor.name, 20286 array: array 20287 }; 20288 20289 } 20290 20291 var attributes = this.attributes; 20292 20293 for ( var key in attributes ) { 20294 20295 var attribute = attributes[ key ]; 20296 20297 var array = Array.prototype.slice.call( attribute.array ); 20298 20299 data.data.attributes[ key ] = { 20300 itemSize: attribute.itemSize, 20301 type: attribute.array.constructor.name, 20302 array: array, 20303 normalized: attribute.normalized 20304 }; 20305 20306 } 20307 20308 var groups = this.groups; 20309 20310 if ( groups.length > 0 ) { 20311 20312 data.data.groups = JSON.parse( JSON.stringify( groups ) ); 20313 20314 } 20315 20316 var boundingSphere = this.boundingSphere; 20317 20318 if ( boundingSphere !== null ) { 20319 20320 data.data.boundingSphere = { 20321 center: boundingSphere.center.toArray(), 20322 radius: boundingSphere.radius 20323 }; 20324 20325 } 20326 20327 return data; 20328 20329 }, 20330
vendor: 30,494 bytes, lines 20331-21606
20331 clone: function () { 20332 20333 /* 20334 // Handle primitives 20335 20336 var parameters = this.parameters; 20337 20338 if ( parameters !== undefined ) { 20339 20340 var values = []; 20341 20342 for ( var key in parameters ) { 20343 20344 values.push( parameters[ key ] ); 20345 20346 } 20347 20348 var geometry = Object.create( this.constructor.prototype ); 20349 this.constructor.apply( geometry, values ); 20350 return geometry; 20351 20352 } 20353 20354 return new this.constructor().copy( this ); 20355 */ 20356 20357 return new BufferGeometry().copy( this ); 20358 20359 }, 20360 20361 copy: function ( source ) { 20362 20363 var name, i, l; 20364 20365 // reset 20366 20367 this.index = null; 20368 this.attributes = {}; 20369 this.morphAttributes = {}; 20370 this.groups = []; 20371 this.boundingBox = null; 20372 this.boundingSphere = null; 20373 20374 // name 20375 20376 this.name = source.name; 20377 20378 // index 20379 20380 var index = source.index; 20381 20382 if ( index !== null ) { 20383 20384 this.setIndex( index.clone() ); 20385 20386 } 20387 20388 // attributes 20389 20390 var attributes = source.attributes; 20391 20392 for ( name in attributes ) { 20393 20394 var attribute = attributes[ name ]; 20395 this.addAttribute( name, attribute.clone() ); 20396 20397 } 20398 20399 // morph attributes 20400 20401 var morphAttributes = source.morphAttributes; 20402 20403 for ( name in morphAttributes ) { 20404 20405 var array = []; 20406 var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes 20407 20408 for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { 20409 20410 array.push( morphAttribute[ i ].clone() ); 20411 20412 } 20413 20414 this.morphAttributes[ name ] = array; 20415 20416 } 20417 20418 // groups 20419 20420 var groups = source.groups; 20421 20422 for ( i = 0, l = groups.length; i < l; i ++ ) { 20423 20424 var group = groups[ i ]; 20425 this.addGroup( group.start, group.count, group.materialIndex ); 20426 20427 } 20428 20429 // bounding box 20430 20431 var boundingBox = source.boundingBox; 20432 20433 if ( boundingBox !== null ) { 20434 20435 this.boundingBox = boundingBox.clone(); 20436 20437 } 20438 20439 // bounding sphere 20440 20441 var boundingSphere = source.boundingSphere; 20442 20443 if ( boundingSphere !== null ) { 20444 20445 this.boundingSphere = boundingSphere.clone(); 20446 20447 } 20448 20449 // draw range 20450 20451 this.drawRange.start = source.drawRange.start; 20452 this.drawRange.count = source.drawRange.count; 20453 20454 // user data 20455 20456 this.userData = source.userData; 20457 20458 return this; 20459 20460 }, 20461 20462 dispose: function () { 20463 20464 this.dispatchEvent( { type: 'dispose' } ); 20465 20466 } 20467 20468 } ); 20469 20470 /** 20471 * @author mrdoob / http://mrdoob.com/ 20472 * @author Mugen87 / https://github.com/Mugen87 20473 */ 20474 20475 // BoxGeometry 20476 20477 function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { 20478 20479 Geometry.call( this ); 20480 20481 this.type = 'BoxGeometry'; 20482 20483 this.parameters = { 20484 width: width, 20485 height: height, 20486 depth: depth, 20487 widthSegments: widthSegments, 20488 heightSegments: heightSegments, 20489 depthSegments: depthSegments 20490 }; 20491 20492 this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); 20493 this.mergeVertices(); 20494 20495 } 20496 20497 BoxGeometry.prototype = Object.create( Geometry.prototype ); 20498 BoxGeometry.prototype.constructor = BoxGeometry; 20499 20500 // BoxBufferGeometry 20501 20502 function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { 20503 20504 BufferGeometry.call( this ); 20505 20506 this.type = 'BoxBufferGeometry'; 20507 20508 this.parameters = { 20509 width: width, 20510 height: height, 20511 depth: depth, 20512 widthSegments: widthSegments, 20513 heightSegments: heightSegments, 20514 depthSegments: depthSegments 20515 }; 20516 20517 var scope = this; 20518 20519 width = width || 1; 20520 height = height || 1; 20521 depth = depth || 1; 20522 20523 // segments 20524 20525 widthSegments = Math.floor( widthSegments ) || 1; 20526 heightSegments = Math.floor( heightSegments ) || 1; 20527 depthSegments = Math.floor( depthSegments ) || 1; 20528 20529 // buffers 20530 20531 var indices = []; 20532 var vertices = []; 20533 var normals = []; 20534 var uvs = []; 20535 20536 // helper variables 20537 20538 var numberOfVertices = 0; 20539 var groupStart = 0; 20540 20541 // build each side of the box geometry 20542 20543 buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px 20544 buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx 20545 buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py 20546 buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny 20547 buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz 20548 buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz 20549 20550 // build geometry 20551 20552 this.setIndex( indices ); 20553 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 20554 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 20555 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 20556 20557 function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { 20558 20559 var segmentWidth = width / gridX; 20560 var segmentHeight = height / gridY; 20561 20562 var widthHalf = width / 2; 20563 var heightHalf = height / 2; 20564 var depthHalf = depth / 2; 20565 20566 var gridX1 = gridX + 1; 20567 var gridY1 = gridY + 1; 20568 20569 var vertexCounter = 0; 20570 var groupCount = 0; 20571 20572 var ix, iy; 20573 20574 var vector = new Vector3(); 20575 20576 // generate vertices, normals and uvs 20577 20578 for ( iy = 0; iy < gridY1; iy ++ ) { 20579 20580 var y = iy * segmentHeight - heightHalf; 20581 20582 for ( ix = 0; ix < gridX1; ix ++ ) { 20583 20584 var x = ix * segmentWidth - widthHalf; 20585 20586 // set values to correct vector component 20587 20588 vector[ u ] = x * udir; 20589 vector[ v ] = y * vdir; 20590 vector[ w ] = depthHalf; 20591 20592 // now apply vector to vertex buffer 20593 20594 vertices.push( vector.x, vector.y, vector.z ); 20595 20596 // set values to correct vector component 20597 20598 vector[ u ] = 0; 20599 vector[ v ] = 0; 20600 vector[ w ] = depth > 0 ? 1 : - 1; 20601 20602 // now apply vector to normal buffer 20603 20604 normals.push( vector.x, vector.y, vector.z ); 20605 20606 // uvs 20607 20608 uvs.push( ix / gridX ); 20609 uvs.push( 1 - ( iy / gridY ) ); 20610 20611 // counters 20612 20613 vertexCounter += 1; 20614 20615 } 20616 20617 } 20618 20619 // indices 20620 20621 // 1. you need three indices to draw a single face 20622 // 2. a single segment consists of two faces 20623 // 3. so we need to generate six (2*3) indices per segment 20624 20625 for ( iy = 0; iy < gridY; iy ++ ) { 20626 20627 for ( ix = 0; ix < gridX; ix ++ ) { 20628 20629 var a = numberOfVertices + ix + gridX1 * iy; 20630 var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); 20631 var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); 20632 var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; 20633 20634 // faces 20635 20636 indices.push( a, b, d ); 20637 indices.push( b, c, d ); 20638 20639 // increase counter 20640 20641 groupCount += 6; 20642 20643 } 20644 20645 } 20646 20647 // add a group to the geometry. this will ensure multi material support 20648 20649 scope.addGroup( groupStart, groupCount, materialIndex ); 20650 20651 // calculate new start value for groups 20652 20653 groupStart += groupCount; 20654 20655 // update total number of vertices 20656 20657 numberOfVertices += vertexCounter; 20658 20659 } 20660 20661 } 20662 20663 BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 20664 BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; 20665 20666 /** 20667 * @author mrdoob / http://mrdoob.com/ 20668 * @author Mugen87 / https://github.com/Mugen87 20669 */ 20670 20671 // PlaneGeometry 20672 20673 function PlaneGeometry( width, height, widthSegments, heightSegments ) { 20674 20675 Geometry.call( this ); 20676 20677 this.type = 'PlaneGeometry'; 20678 20679 this.parameters = { 20680 width: width, 20681 height: height, 20682 widthSegments: widthSegments, 20683 heightSegments: heightSegments 20684 }; 20685 20686 this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); 20687 this.mergeVertices(); 20688 20689 } 20690 20691 PlaneGeometry.prototype = Object.create( Geometry.prototype ); 20692 PlaneGeometry.prototype.constructor = PlaneGeometry; 20693 20694 // PlaneBufferGeometry 20695 20696 function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { 20697 20698 BufferGeometry.call( this ); 20699 20700 this.type = 'PlaneBufferGeometry'; 20701 20702 this.parameters = { 20703 width: width, 20704 height: height, 20705 widthSegments: widthSegments, 20706 heightSegments: heightSegments 20707 }; 20708 20709 width = width || 1; 20710 height = height || 1; 20711 20712 var width_half = width / 2; 20713 var height_half = height / 2; 20714 20715 var gridX = Math.floor( widthSegments ) || 1; 20716 var gridY = Math.floor( heightSegments ) || 1; 20717 20718 var gridX1 = gridX + 1; 20719 var gridY1 = gridY + 1; 20720 20721 var segment_width = width / gridX; 20722 var segment_height = height / gridY; 20723 20724 var ix, iy; 20725 20726 // buffers 20727 20728 var indices = []; 20729 var vertices = []; 20730 var normals = []; 20731 var uvs = []; 20732 20733 // generate vertices, normals and uvs 20734 20735 for ( iy = 0; iy < gridY1; iy ++ ) { 20736 20737 var y = iy * segment_height - height_half; 20738 20739 for ( ix = 0; ix < gridX1; ix ++ ) { 20740 20741 var x = ix * segment_width - width_half; 20742 20743 vertices.push( x, - y, 0 ); 20744 20745 normals.push( 0, 0, 1 ); 20746 20747 uvs.push( ix / gridX ); 20748 uvs.push( 1 - ( iy / gridY ) ); 20749 20750 } 20751 20752 } 20753 20754 // indices 20755 20756 for ( iy = 0; iy < gridY; iy ++ ) { 20757 20758 for ( ix = 0; ix < gridX; ix ++ ) { 20759 20760 var a = ix + gridX1 * iy; 20761 var b = ix + gridX1 * ( iy + 1 ); 20762 var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); 20763 var d = ( ix + 1 ) + gridX1 * iy; 20764 20765 // faces 20766 20767 indices.push( a, b, d ); 20768 indices.push( b, c, d ); 20769 20770 } 20771 20772 } 20773 20774 // build geometry 20775 20776 this.setIndex( indices ); 20777 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 20778 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 20779 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 20780 20781 } 20782 20783 PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 20784 PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; 20785 20786 /** 20787 * @author mrdoob / http://mrdoob.com/ 20788 * @author alteredq / http://alteredqualia.com/ 20789 */ 20790 20791 var materialId = 0; 20792 20793 function Material() { 20794 20795 Object.defineProperty( this, 'id', { value: materialId ++ } ); 20796 20797 this.uuid = _Math.generateUUID(); 20798 20799 this.name = ''; 20800 this.type = 'Material'; 20801 20802 this.fog = true; 20803 this.lights = true; 20804 20805 this.blending = NormalBlending; 20806 this.side = FrontSide; 20807 this.flatShading = false; 20808 this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors 20809 20810 this.opacity = 1; 20811 this.transparent = false; 20812 20813 this.blendSrc = SrcAlphaFactor; 20814 this.blendDst = OneMinusSrcAlphaFactor; 20815 this.blendEquation = AddEquation; 20816 this.blendSrcAlpha = null; 20817 this.blendDstAlpha = null; 20818 this.blendEquationAlpha = null; 20819 20820 this.depthFunc = LessEqualDepth; 20821 this.depthTest = true; 20822 this.depthWrite = true; 20823 20824 this.clippingPlanes = null; 20825 this.clipIntersection = false; 20826 this.clipShadows = false; 20827 20828 this.shadowSide = null; 20829 20830 this.colorWrite = true; 20831 20832 this.precision = null; // override the renderer's default precision for this material 20833 20834 this.polygonOffset = false; 20835 this.polygonOffsetFactor = 0; 20836 this.polygonOffsetUnits = 0; 20837 20838 this.dithering = false; 20839 20840 this.alphaTest = 0; 20841 this.premultipliedAlpha = false; 20842 20843 this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer 20844 20845 this.visible = true; 20846 20847 this.userData = {}; 20848 20849 this.needsUpdate = true; 20850 20851 } 20852 20853 Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 20854 20855 constructor: Material, 20856 20857 isMaterial: true, 20858 20859 onBeforeCompile: function () {}, 20860 20861 setValues: function ( values ) { 20862 20863 if ( values === undefined ) return; 20864 20865 for ( var key in values ) { 20866 20867 var newValue = values[ key ]; 20868 20869 if ( newValue === undefined ) { 20870 20871 console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); 20872 continue; 20873 20874 } 20875 20876 // for backward compatability if shading is set in the constructor 20877 if ( key === 'shading' ) { 20878 20879 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 20880 this.flatShading = ( newValue === FlatShading ) ? true : false; 20881 continue; 20882 20883 } 20884 20885 var currentValue = this[ key ]; 20886 20887 if ( currentValue === undefined ) { 20888 20889 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); 20890 continue; 20891 20892 } 20893 20894 if ( currentValue && currentValue.isColor ) { 20895 20896 currentValue.set( newValue ); 20897 20898 } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { 20899 20900 currentValue.copy( newValue ); 20901 20902 } else if ( key === 'overdraw' ) { 20903 20904 // ensure overdraw is backwards-compatible with legacy boolean type 20905 this[ key ] = Number( newValue ); 20906 20907 } else { 20908 20909 this[ key ] = newValue; 20910 20911 } 20912 20913 } 20914 20915 }, 20916 20917 toJSON: function ( meta ) { 20918 20919 var isRoot = ( meta === undefined || typeof meta === 'string' ); 20920 20921 if ( isRoot ) { 20922 20923 meta = { 20924 textures: {}, 20925 images: {} 20926 }; 20927 20928 } 20929 20930 var data = { 20931 metadata: { 20932 version: 4.5, 20933 type: 'Material', 20934 generator: 'Material.toJSON' 20935 } 20936 }; 20937 20938 // standard Material serialization 20939 data.uuid = this.uuid; 20940 data.type = this.type; 20941 20942 if ( this.name !== '' ) data.name = this.name; 20943 20944 if ( this.color && this.color.isColor ) data.color = this.color.getHex(); 20945 20946 if ( this.roughness !== undefined ) data.roughness = this.roughness; 20947 if ( this.metalness !== undefined ) data.metalness = this.metalness; 20948 20949 if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); 20950 if ( this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; 20951 20952 if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); 20953 if ( this.shininess !== undefined ) data.shininess = this.shininess; 20954 if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; 20955 if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; 20956 20957 if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; 20958 if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; 20959 if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; 20960 20961 if ( this.aoMap && this.aoMap.isTexture ) { 20962 20963 data.aoMap = this.aoMap.toJSON( meta ).uuid; 20964 data.aoMapIntensity = this.aoMapIntensity; 20965 20966 } 20967 20968 if ( this.bumpMap && this.bumpMap.isTexture ) { 20969 20970 data.bumpMap = this.bumpMap.toJSON( meta ).uuid; 20971 data.bumpScale = this.bumpScale; 20972 20973 } 20974 20975 if ( this.normalMap && this.normalMap.isTexture ) { 20976 20977 data.normalMap = this.normalMap.toJSON( meta ).uuid; 20978 data.normalScale = this.normalScale.toArray(); 20979 20980 } 20981 20982 if ( this.displacementMap && this.displacementMap.isTexture ) { 20983 20984 data.displacementMap = this.displacementMap.toJSON( meta ).uuid; 20985 data.displacementScale = this.displacementScale; 20986 data.displacementBias = this.displacementBias; 20987 20988 } 20989 20990 if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; 20991 if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; 20992 20993 if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; 20994 if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; 20995 20996 if ( this.envMap && this.envMap.isTexture ) { 20997 20998 data.envMap = this.envMap.toJSON( meta ).uuid; 20999 data.reflectivity = this.reflectivity; // Scale behind envMap 21000 21001 } 21002 21003 if ( this.gradientMap && this.gradientMap.isTexture ) { 21004 21005 data.gradientMap = this.gradientMap.toJSON( meta ).uuid; 21006 21007 } 21008 21009 if ( this.size !== undefined ) data.size = this.size; 21010 if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; 21011 21012 if ( this.blending !== NormalBlending ) data.blending = this.blending; 21013 if ( this.flatShading === true ) data.flatShading = this.flatShading; 21014 if ( this.side !== FrontSide ) data.side = this.side; 21015 if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; 21016 21017 if ( this.opacity < 1 ) data.opacity = this.opacity; 21018 if ( this.transparent === true ) data.transparent = this.transparent; 21019 21020 data.depthFunc = this.depthFunc; 21021 data.depthTest = this.depthTest; 21022 data.depthWrite = this.depthWrite; 21023 21024 // rotation (SpriteMaterial) 21025 if ( this.rotation !== 0 ) data.rotation = this.rotation; 21026 21027 if ( this.linewidth !== 1 ) data.linewidth = this.linewidth; 21028 if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; 21029 if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; 21030 if ( this.scale !== undefined ) data.scale = this.scale; 21031 21032 if ( this.dithering === true ) data.dithering = true; 21033 21034 if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; 21035 if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; 21036 21037 if ( this.wireframe === true ) data.wireframe = this.wireframe; 21038 if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; 21039 if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; 21040 if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; 21041 21042 if ( this.morphTargets === true ) data.morphTargets = true; 21043 if ( this.skinning === true ) data.skinning = true; 21044 21045 if ( this.visible === false ) data.visible = false; 21046 if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; 21047 21048 // TODO: Copied from Object3D.toJSON 21049 21050 function extractFromCache( cache ) { 21051 21052 var values = []; 21053 21054 for ( var key in cache ) { 21055 21056 var data = cache[ key ]; 21057 delete data.metadata; 21058 values.push( data ); 21059 21060 } 21061 21062 return values; 21063 21064 } 21065 21066 if ( isRoot ) { 21067 21068 var textures = extractFromCache( meta.textures ); 21069 var images = extractFromCache( meta.images ); 21070 21071 if ( textures.length > 0 ) data.textures = textures; 21072 if ( images.length > 0 ) data.images = images; 21073 21074 } 21075 21076 return data; 21077 21078 }, 21079 21080 clone: function () { 21081 21082 return new this.constructor().copy( this ); 21083 21084 }, 21085 21086 copy: function ( source ) { 21087 21088 this.name = source.name; 21089 21090 this.fog = source.fog; 21091 this.lights = source.lights; 21092 21093 this.blending = source.blending; 21094 this.side = source.side; 21095 this.flatShading = source.flatShading; 21096 this.vertexColors = source.vertexColors; 21097 21098 this.opacity = source.opacity; 21099 this.transparent = source.transparent; 21100 21101 this.blendSrc = source.blendSrc; 21102 this.blendDst = source.blendDst; 21103 this.blendEquation = source.blendEquation; 21104 this.blendSrcAlpha = source.blendSrcAlpha; 21105 this.blendDstAlpha = source.blendDstAlpha; 21106 this.blendEquationAlpha = source.blendEquationAlpha; 21107 21108 this.depthFunc = source.depthFunc; 21109 this.depthTest = source.depthTest; 21110 this.depthWrite = source.depthWrite; 21111 21112 this.colorWrite = source.colorWrite; 21113 21114 this.precision = source.precision; 21115 21116 this.polygonOffset = source.polygonOffset; 21117 this.polygonOffsetFactor = source.polygonOffsetFactor; 21118 this.polygonOffsetUnits = source.polygonOffsetUnits; 21119 21120 this.dithering = source.dithering; 21121 21122 this.alphaTest = source.alphaTest; 21123 this.premultipliedAlpha = source.premultipliedAlpha; 21124 21125 this.overdraw = source.overdraw; 21126 21127 this.visible = source.visible; 21128 this.userData = JSON.parse( JSON.stringify( source.userData ) ); 21129 21130 this.clipShadows = source.clipShadows; 21131 this.clipIntersection = source.clipIntersection; 21132 21133 var srcPlanes = source.clippingPlanes, 21134 dstPlanes = null; 21135 21136 if ( srcPlanes !== null ) { 21137 21138 var n = srcPlanes.length; 21139 dstPlanes = new Array( n ); 21140 21141 for ( var i = 0; i !== n; ++ i ) 21142 dstPlanes[ i ] = srcPlanes[ i ].clone(); 21143 21144 } 21145 21146 this.clippingPlanes = dstPlanes; 21147 21148 this.shadowSide = source.shadowSide; 21149 21150 return this; 21151 21152 }, 21153 21154 dispose: function () { 21155 21156 this.dispatchEvent( { type: 'dispose' } ); 21157 21158 } 21159 21160 } ); 21161 21162 /** 21163 * @author mrdoob / http://mrdoob.com/ 21164 * @author alteredq / http://alteredqualia.com/ 21165 * 21166 * parameters = { 21167 * color: <hex>, 21168 * opacity: <float>, 21169 * map: new THREE.Texture( <Image> ), 21170 * 21171 * lightMap: new THREE.Texture( <Image> ), 21172 * lightMapIntensity: <float> 21173 * 21174 * aoMap: new THREE.Texture( <Image> ), 21175 * aoMapIntensity: <float> 21176 * 21177 * specularMap: new THREE.Texture( <Image> ), 21178 * 21179 * alphaMap: new THREE.Texture( <Image> ), 21180 * 21181 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 21182 * combine: THREE.Multiply, 21183 * reflectivity: <float>, 21184 * refractionRatio: <float>, 21185 * 21186 * depthTest: <bool>, 21187 * depthWrite: <bool>, 21188 * 21189 * wireframe: <boolean>, 21190 * wireframeLinewidth: <float>, 21191 * 21192 * skinning: <bool>, 21193 * morphTargets: <bool> 21194 * } 21195 */ 21196 21197 function MeshBasicMaterial( parameters ) { 21198 21199 Material.call( this ); 21200 21201 this.type = 'MeshBasicMaterial'; 21202 21203 this.color = new Color( 0xffffff ); // emissive 21204 21205 this.map = null; 21206 21207 this.lightMap = null; 21208 this.lightMapIntensity = 1.0; 21209 21210 this.aoMap = null; 21211 this.aoMapIntensity = 1.0; 21212 21213 this.specularMap = null; 21214 21215 this.alphaMap = null; 21216 21217 this.envMap = null; 21218 this.combine = MultiplyOperation; 21219 this.reflectivity = 1; 21220 this.refractionRatio = 0.98; 21221 21222 this.wireframe = false; 21223 this.wireframeLinewidth = 1; 21224 this.wireframeLinecap = 'round'; 21225 this.wireframeLinejoin = 'round'; 21226 21227 this.skinning = false; 21228 this.morphTargets = false; 21229 21230 this.lights = false; 21231 21232 this.setValues( parameters ); 21233 21234 } 21235 21236 MeshBasicMaterial.prototype = Object.create( Material.prototype ); 21237 MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; 21238 21239 MeshBasicMaterial.prototype.isMeshBasicMaterial = true; 21240 21241 MeshBasicMaterial.prototype.copy = function ( source ) { 21242 21243 Material.prototype.copy.call( this, source ); 21244 21245 this.color.copy( source.color ); 21246 21247 this.map = source.map; 21248 21249 this.lightMap = source.lightMap; 21250 this.lightMapIntensity = source.lightMapIntensity; 21251 21252 this.aoMap = source.aoMap; 21253 this.aoMapIntensity = source.aoMapIntensity; 21254 21255 this.specularMap = source.specularMap; 21256 21257 this.alphaMap = source.alphaMap; 21258 21259 this.envMap = source.envMap; 21260 this.combine = source.combine; 21261 this.reflectivity = source.reflectivity; 21262 this.refractionRatio = source.refractionRatio; 21263 21264 this.wireframe = source.wireframe; 21265 this.wireframeLinewidth = source.wireframeLinewidth; 21266 this.wireframeLinecap = source.wireframeLinecap; 21267 this.wireframeLinejoin = source.wireframeLinejoin; 21268 21269 this.skinning = source.skinning; 21270 this.morphTargets = source.morphTargets; 21271 21272 return this; 21273 21274 }; 21275 21276 /** 21277 * @author alteredq / http://alteredqualia.com/ 21278 * 21279 * parameters = { 21280 * defines: { "label" : "value" }, 21281 * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, 21282 * 21283 * fragmentShader: <string>, 21284 * vertexShader: <string>, 21285 * 21286 * wireframe: <boolean>, 21287 * wireframeLinewidth: <float>, 21288 * 21289 * lights: <bool>, 21290 * 21291 * skinning: <bool>, 21292 * morphTargets: <bool>, 21293 * morphNormals: <bool> 21294 * } 21295 */ 21296 21297 function ShaderMaterial( parameters ) { 21298 21299 Material.call( this ); 21300 21301 this.type = 'ShaderMaterial'; 21302 21303 this.defines = {}; 21304 this.uniforms = {}; 21305 21306 this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}'; 21307 this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}'; 21308 21309 this.linewidth = 1; 21310 21311 this.wireframe = false; 21312 this.wireframeLinewidth = 1; 21313 21314 this.fog = false; // set to use scene fog 21315 this.lights = false; // set to use scene lights 21316 this.clipping = false; // set to use user-defined clipping planes 21317 21318 this.skinning = false; // set to use skinning attribute streams 21319 this.morphTargets = false; // set to use morph targets 21320 this.morphNormals = false; // set to use morph normals 21321 21322 this.extensions = { 21323 derivatives: false, // set to use derivatives 21324 fragDepth: false, // set to use fragment depth values 21325 drawBuffers: false, // set to use draw buffers 21326 shaderTextureLOD: false // set to use shader texture LOD 21327 }; 21328 21329 // When rendered geometry doesn't include these attributes but the material does, 21330 // use these default values in WebGL. This avoids errors when buffer data is missing. 21331 this.defaultAttributeValues = { 21332 'color': [ 1, 1, 1 ], 21333 'uv': [ 0, 0 ], 21334 'uv2': [ 0, 0 ] 21335 }; 21336 21337 this.index0AttributeName = undefined; 21338 this.uniformsNeedUpdate = false; 21339 21340 if ( parameters !== undefined ) { 21341 21342 if ( parameters.attributes !== undefined ) { 21343 21344 console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); 21345 21346 } 21347 21348 this.setValues( parameters ); 21349 21350 } 21351 21352 } 21353 21354 ShaderMaterial.prototype = Object.create( Material.prototype ); 21355 ShaderMaterial.prototype.constructor = ShaderMaterial; 21356 21357 ShaderMaterial.prototype.isShaderMaterial = true; 21358 21359 ShaderMaterial.prototype.copy = function ( source ) { 21360 21361 Material.prototype.copy.call( this, source ); 21362 21363 this.fragmentShader = source.fragmentShader; 21364 this.vertexShader = source.vertexShader; 21365 21366 this.uniforms = UniformsUtils.clone( source.uniforms ); 21367 21368 this.defines = Object.assign( {}, source.defines ); 21369 21370 this.wireframe = source.wireframe; 21371 this.wireframeLinewidth = source.wireframeLinewidth; 21372 21373 this.lights = source.lights; 21374 this.clipping = source.clipping; 21375 21376 this.skinning = source.skinning; 21377 21378 this.morphTargets = source.morphTargets; 21379 this.morphNormals = source.morphNormals; 21380 21381 this.extensions = source.extensions; 21382 21383 return this; 21384 21385 }; 21386 21387 ShaderMaterial.prototype.toJSON = function ( meta ) { 21388 21389 var data = Material.prototype.toJSON.call( this, meta ); 21390 21391 data.uniforms = this.uniforms; 21392 data.vertexShader = this.vertexShader; 21393 data.fragmentShader = this.fragmentShader; 21394 21395 return data; 21396 21397 }; 21398 21399 /** 21400 * @author bhouston / http://clara.io 21401 */ 21402 21403 function Ray( origin, direction ) { 21404 21405 this.origin = ( origin !== undefined ) ? origin : new Vector3(); 21406 this.direction = ( direction !== undefined ) ? direction : new Vector3(); 21407 21408 } 21409 21410 Object.assign( Ray.prototype, { 21411 21412 set: function ( origin, direction ) { 21413 21414 this.origin.copy( origin ); 21415 this.direction.copy( direction ); 21416 21417 return this; 21418 21419 }, 21420 21421 clone: function () { 21422 21423 return new this.constructor().copy( this ); 21424 21425 }, 21426 21427 copy: function ( ray ) { 21428 21429 this.origin.copy( ray.origin ); 21430 this.direction.copy( ray.direction ); 21431 21432 return this; 21433 21434 }, 21435 21436 at: function ( t, target ) { 21437 21438 if ( target === undefined ) { 21439 21440 console.warn( 'THREE.Ray: .at() target is now required' ); 21441 target = new Vector3(); 21442 21443 } 21444 21445 return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); 21446 21447 }, 21448 21449 lookAt: function ( v ) { 21450 21451 this.direction.copy( v ).sub( this.origin ).normalize(); 21452 21453 return this; 21454 21455 }, 21456 21457 recast: function () { 21458 21459 var v1 = new Vector3(); 21460 21461 return function recast( t ) { 21462 21463 this.origin.copy( this.at( t, v1 ) ); 21464 21465 return this; 21466 21467 }; 21468 21469 }(), 21470 21471 closestPointToPoint: function ( point, target ) { 21472 21473 if ( target === undefined ) { 21474 21475 console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); 21476 target = new Vector3(); 21477 21478 } 21479 21480 target.subVectors( point, this.origin ); 21481 21482 var directionDistance = target.dot( this.direction ); 21483 21484 if ( directionDistance < 0 ) { 21485 21486 return target.copy( this.origin ); 21487 21488 } 21489 21490 return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); 21491 21492 }, 21493 21494 distanceToPoint: function ( point ) { 21495 21496 return Math.sqrt( this.distanceSqToPoint( point ) ); 21497 21498 }, 21499 21500 distanceSqToPoint: function () { 21501 21502 var v1 = new Vector3(); 21503 21504 return function distanceSqToPoint( point ) { 21505 21506 var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); 21507 21508 // point behind the ray 21509 21510 if ( directionDistance < 0 ) { 21511 21512 return this.origin.distanceToSquared( point ); 21513 21514 } 21515 21516 v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); 21517 21518 return v1.distanceToSquared( point ); 21519 21520 }; 21521 21522 }(), 21523 21524 distanceSqToSegment: function () { 21525 21526 var segCenter = new Vector3(); 21527 var segDir = new Vector3(); 21528 var diff = new Vector3(); 21529 21530 return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { 21531 21532 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h 21533 // It returns the min distance between the ray and the segment 21534 // defined by v0 and v1 21535 // It can also set two optional targets : 21536 // - The closest point on the ray 21537 // - The closest point on the segment 21538 21539 segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); 21540 segDir.copy( v1 ).sub( v0 ).normalize(); 21541 diff.copy( this.origin ).sub( segCenter ); 21542 21543 var segExtent = v0.distanceTo( v1 ) * 0.5; 21544 var a01 = - this.direction.dot( segDir ); 21545 var b0 = diff.dot( this.direction ); 21546 var b1 = - diff.dot( segDir ); 21547 var c = diff.lengthSq(); 21548 var det = Math.abs( 1 - a01 * a01 ); 21549 var s0, s1, sqrDist, extDet; 21550 21551 if ( det > 0 ) { 21552 21553 // The ray and segment are not parallel. 21554 21555 s0 = a01 * b1 - b0; 21556 s1 = a01 * b0 - b1; 21557 extDet = segExtent * det; 21558 21559 if ( s0 >= 0 ) { 21560 21561 if ( s1 >= - extDet ) { 21562 21563 if ( s1 <= extDet ) { 21564 21565 // region 0 21566 // Minimum at interior points of ray and segment. 21567 21568 var invDet = 1 / det; 21569 s0 *= invDet; 21570 s1 *= invDet; 21571 sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; 21572 21573 } else { 21574 21575 // region 1 21576 21577 s1 = segExtent; 21578 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 21579 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 21580 21581 } 21582 21583 } else { 21584 21585 // region 5 21586 21587 s1 = - segExtent; 21588 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 21589 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 21590 21591 } 21592 21593 } else { 21594 21595 if ( s1 <= - extDet ) { 21596 21597 // region 4 21598 21599 s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); 21600 s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); 21601 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 21602 21603 } else if ( s1 <= extDet ) { 21604 21605 // region 3 21606
vendor: 4,199 bytes, lines 21607-21796
21607 s0 = 0; 21608 s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); 21609 sqrDist = s1 * ( s1 + 2 * b1 ) + c; 21610 21611 } else { 21612 21613 // region 2 21614 21615 s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); 21616 s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); 21617 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 21618 21619 } 21620 21621 } 21622 21623 } else { 21624 21625 // Ray and segment are parallel. 21626 21627 s1 = ( a01 > 0 ) ? - segExtent : segExtent; 21628 s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); 21629 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; 21630 21631 } 21632 21633 if ( optionalPointOnRay ) { 21634 21635 optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); 21636 21637 } 21638 21639 if ( optionalPointOnSegment ) { 21640 21641 optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); 21642 21643 } 21644 21645 return sqrDist; 21646 21647 }; 21648 21649 }(), 21650 21651 intersectSphere: function () { 21652 21653 var v1 = new Vector3(); 21654 21655 return function intersectSphere( sphere, target ) { 21656 21657 v1.subVectors( sphere.center, this.origin ); 21658 var tca = v1.dot( this.direction ); 21659 var d2 = v1.dot( v1 ) - tca * tca; 21660 var radius2 = sphere.radius * sphere.radius; 21661 21662 if ( d2 > radius2 ) return null; 21663 21664 var thc = Math.sqrt( radius2 - d2 ); 21665 21666 // t0 = first intersect point - entrance on front of sphere 21667 var t0 = tca - thc; 21668 21669 // t1 = second intersect point - exit point on back of sphere 21670 var t1 = tca + thc; 21671 21672 // test to see if both t0 and t1 are behind the ray - if so, return null 21673 if ( t0 < 0 && t1 < 0 ) return null; 21674 21675 // test to see if t0 is behind the ray: 21676 // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, 21677 // in order to always return an intersect point that is in front of the ray. 21678 if ( t0 < 0 ) return this.at( t1, target ); 21679 21680 // else t0 is in front of the ray, so return the first collision point scaled by t0 21681 return this.at( t0, target ); 21682 21683 }; 21684 21685 }(), 21686 21687 intersectsSphere: function ( sphere ) { 21688 21689 return this.distanceToPoint( sphere.center ) <= sphere.radius; 21690 21691 }, 21692 21693 distanceToPlane: function ( plane ) { 21694 21695 var denominator = plane.normal.dot( this.direction ); 21696 21697 if ( denominator === 0 ) { 21698 21699 // line is coplanar, return origin 21700 if ( plane.distanceToPoint( this.origin ) === 0 ) { 21701 21702 return 0; 21703 21704 } 21705 21706 // Null is preferable to undefined since undefined means.... it is undefined 21707 21708 return null; 21709 21710 } 21711 21712 var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; 21713 21714 // Return if the ray never intersects the plane 21715 21716 return t >= 0 ? t : null; 21717 21718 }, 21719 21720 intersectPlane: function ( plane, target ) { 21721 21722 var t = this.distanceToPlane( plane ); 21723 21724 if ( t === null ) { 21725 21726 return null; 21727 21728 } 21729 21730 return this.at( t, target ); 21731 21732 }, 21733 21734 intersectsPlane: function ( plane ) { 21735 21736 // check if the ray lies on the plane first 21737 21738 var distToPoint = plane.distanceToPoint( this.origin ); 21739 21740 if ( distToPoint === 0 ) { 21741 21742 return true; 21743 21744 } 21745 21746 var denominator = plane.normal.dot( this.direction ); 21747 21748 if ( denominator * distToPoint < 0 ) { 21749 21750 return true; 21751 21752 } 21753 21754 // ray origin is behind the plane (and is pointing behind it) 21755 21756 return false; 21757 21758 }, 21759 21760 intersectBox: function ( box, target ) { 21761 21762 var tmin, tmax, tymin, tymax, tzmin, tzmax; 21763 21764 var invdirx = 1 / this.direction.x, 21765 invdiry = 1 / this.direction.y, 21766 invdirz = 1 / this.direction.z; 21767 21768 var origin = this.origin; 21769 21770 if ( invdirx >= 0 ) { 21771 21772 tmin = ( box.min.x - origin.x ) * invdirx; 21773 tmax = ( box.max.x - origin.x ) * invdirx; 21774 21775 } else { 21776 21777 tmin = ( box.max.x - origin.x ) * invdirx; 21778 tmax = ( box.min.x - origin.x ) * invdirx; 21779 21780 } 21781 21782 if ( invdiry >= 0 ) { 21783 21784 tymin = ( box.min.y - origin.y ) * invdiry; 21785 tymax = ( box.max.y - origin.y ) * invdiry; 21786 21787 } else { 21788 21789 tymin = ( box.max.y - origin.y ) * invdiry; 21790 tymax = ( box.min.y - origin.y ) * invdiry; 21791 21792 } 21793 21794 if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; 21795 21796 // These lines also handle the case where tmin or tmax is NaN
vendor: 7,806 bytes, lines 21797-22174
21797 // (result of 0 * Infinity). x !== x returns true if x is NaN 21798 21799 if ( tymin > tmin || tmin !== tmin ) tmin = tymin; 21800 21801 if ( tymax < tmax || tmax !== tmax ) tmax = tymax; 21802 21803 if ( invdirz >= 0 ) { 21804 21805 tzmin = ( box.min.z - origin.z ) * invdirz; 21806 tzmax = ( box.max.z - origin.z ) * invdirz; 21807 21808 } else { 21809 21810 tzmin = ( box.max.z - origin.z ) * invdirz; 21811 tzmax = ( box.min.z - origin.z ) * invdirz; 21812 21813 } 21814 21815 if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; 21816 21817 if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; 21818 21819 if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; 21820 21821 //return point closest to the ray (positive side) 21822 21823 if ( tmax < 0 ) return null; 21824 21825 return this.at( tmin >= 0 ? tmin : tmax, target ); 21826 21827 }, 21828 21829 intersectsBox: ( function () { 21830 21831 var v = new Vector3(); 21832 21833 return function intersectsBox( box ) { 21834 21835 return this.intersectBox( box, v ) !== null; 21836 21837 }; 21838 21839 } )(), 21840 21841 intersectTriangle: function () { 21842 21843 // Compute the offset origin, edges, and normal. 21844 var diff = new Vector3(); 21845 var edge1 = new Vector3(); 21846 var edge2 = new Vector3(); 21847 var normal = new Vector3(); 21848 21849 return function intersectTriangle( a, b, c, backfaceCulling, target ) { 21850 21851 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h 21852 21853 edge1.subVectors( b, a ); 21854 edge2.subVectors( c, a ); 21855 normal.crossVectors( edge1, edge2 ); 21856 21857 // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, 21858 // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by 21859 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) 21860 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) 21861 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) 21862 var DdN = this.direction.dot( normal ); 21863 var sign; 21864 21865 if ( DdN > 0 ) { 21866 21867 if ( backfaceCulling ) return null; 21868 sign = 1; 21869 21870 } else if ( DdN < 0 ) { 21871 21872 sign = - 1; 21873 DdN = - DdN; 21874 21875 } else { 21876 21877 return null; 21878 21879 } 21880 21881 diff.subVectors( this.origin, a ); 21882 var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); 21883 21884 // b1 < 0, no intersection 21885 if ( DdQxE2 < 0 ) { 21886 21887 return null; 21888 21889 } 21890 21891 var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); 21892 21893 // b2 < 0, no intersection 21894 if ( DdE1xQ < 0 ) { 21895 21896 return null; 21897 21898 } 21899 21900 // b1+b2 > 1, no intersection 21901 if ( DdQxE2 + DdE1xQ > DdN ) { 21902 21903 return null; 21904 21905 } 21906 21907 // Line intersects triangle, check if ray does. 21908 var QdN = - sign * diff.dot( normal ); 21909 21910 // t < 0, no intersection 21911 if ( QdN < 0 ) { 21912 21913 return null; 21914 21915 } 21916 21917 // Ray intersects triangle. 21918 return this.at( QdN / DdN, target ); 21919 21920 }; 21921 21922 }(), 21923 21924 applyMatrix4: function ( matrix4 ) { 21925 21926 this.origin.applyMatrix4( matrix4 ); 21927 this.direction.transformDirection( matrix4 ); 21928 21929 return this; 21930 21931 }, 21932 21933 equals: function ( ray ) { 21934 21935 return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); 21936 21937 } 21938 21939 } ); 21940 21941 /** 21942 * @author bhouston / http://clara.io 21943 */ 21944 21945 function Line3( start, end ) { 21946 21947 this.start = ( start !== undefined ) ? start : new Vector3(); 21948 this.end = ( end !== undefined ) ? end : new Vector3(); 21949 21950 } 21951 21952 Object.assign( Line3.prototype, { 21953 21954 set: function ( start, end ) { 21955 21956 this.start.copy( start ); 21957 this.end.copy( end ); 21958 21959 return this; 21960 21961 }, 21962 21963 clone: function () { 21964 21965 return new this.constructor().copy( this ); 21966 21967 }, 21968 21969 copy: function ( line ) { 21970 21971 this.start.copy( line.start ); 21972 this.end.copy( line.end ); 21973 21974 return this; 21975 21976 }, 21977 21978 getCenter: function ( target ) { 21979 21980 if ( target === undefined ) { 21981 21982 console.warn( 'THREE.Line3: .getCenter() target is now required' ); 21983 target = new Vector3(); 21984 21985 } 21986 21987 return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); 21988 21989 }, 21990 21991 delta: function ( target ) { 21992 21993 if ( target === undefined ) { 21994 21995 console.warn( 'THREE.Line3: .delta() target is now required' ); 21996 target = new Vector3(); 21997 21998 } 21999 22000 return target.subVectors( this.end, this.start ); 22001 22002 }, 22003 22004 distanceSq: function () { 22005 22006 return this.start.distanceToSquared( this.end ); 22007 22008 }, 22009 22010 distance: function () { 22011 22012 return this.start.distanceTo( this.end ); 22013 22014 }, 22015 22016 at: function ( t, target ) { 22017 22018 if ( target === undefined ) { 22019 22020 console.warn( 'THREE.Line3: .at() target is now required' ); 22021 target = new Vector3(); 22022 22023 } 22024 22025 return this.delta( target ).multiplyScalar( t ).add( this.start ); 22026 22027 }, 22028 22029 closestPointToPointParameter: function () { 22030 22031 var startP = new Vector3(); 22032 var startEnd = new Vector3(); 22033 22034 return function closestPointToPointParameter( point, clampToLine ) { 22035 22036 startP.subVectors( point, this.start ); 22037 startEnd.subVectors( this.end, this.start ); 22038 22039 var startEnd2 = startEnd.dot( startEnd ); 22040 var startEnd_startP = startEnd.dot( startP ); 22041 22042 var t = startEnd_startP / startEnd2; 22043 22044 if ( clampToLine ) { 22045 22046 t = _Math.clamp( t, 0, 1 ); 22047 22048 } 22049 22050 return t; 22051 22052 }; 22053 22054 }(), 22055 22056 closestPointToPoint: function ( point, clampToLine, target ) { 22057 22058 var t = this.closestPointToPointParameter( point, clampToLine ); 22059 22060 if ( target === undefined ) { 22061 22062 console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' ); 22063 target = new Vector3(); 22064 22065 } 22066 22067 return this.delta( target ).multiplyScalar( t ).add( this.start ); 22068 22069 }, 22070 22071 applyMatrix4: function ( matrix ) { 22072 22073 this.start.applyMatrix4( matrix ); 22074 this.end.applyMatrix4( matrix ); 22075 22076 return this; 22077 22078 }, 22079 22080 equals: function ( line ) { 22081 22082 return line.start.equals( this.start ) && line.end.equals( this.end ); 22083 22084 } 22085 22086 } ); 22087 22088 /** 22089 * @author bhouston / http://clara.io 22090 * @author mrdoob / http://mrdoob.com/ 22091 */ 22092 22093 function Triangle( a, b, c ) { 22094 22095 this.a = ( a !== undefined ) ? a : new Vector3(); 22096 this.b = ( b !== undefined ) ? b : new Vector3(); 22097 this.c = ( c !== undefined ) ? c : new Vector3(); 22098 22099 } 22100 22101 Object.assign( Triangle, { 22102 22103 getNormal: function () { 22104 22105 var v0 = new Vector3(); 22106 22107 return function getNormal( a, b, c, target ) { 22108 22109 if ( target === undefined ) { 22110 22111 console.warn( 'THREE.Triangle: .getNormal() target is now required' ); 22112 target = new Vector3(); 22113 22114 } 22115 22116 target.subVectors( c, b ); 22117 v0.subVectors( a, b ); 22118 target.cross( v0 ); 22119 22120 var targetLengthSq = target.lengthSq(); 22121 if ( targetLengthSq > 0 ) { 22122 22123 return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); 22124 22125 } 22126 22127 return target.set( 0, 0, 0 ); 22128 22129 }; 22130 22131 }(), 22132 22133 // static/instance method to calculate barycentric coordinates 22134 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html 22135 getBarycoord: function () { 22136 22137 var v0 = new Vector3(); 22138 var v1 = new Vector3(); 22139 var v2 = new Vector3(); 22140 22141 return function getBarycoord( point, a, b, c, target ) { 22142 22143 v0.subVectors( c, a ); 22144 v1.subVectors( b, a ); 22145 v2.subVectors( point, a ); 22146 22147 var dot00 = v0.dot( v0 ); 22148 var dot01 = v0.dot( v1 ); 22149 var dot02 = v0.dot( v2 ); 22150 var dot11 = v1.dot( v1 ); 22151 var dot12 = v1.dot( v2 ); 22152 22153 var denom = ( dot00 * dot11 - dot01 * dot01 ); 22154 22155 if ( target === undefined ) { 22156 22157 console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); 22158 target = new Vector3(); 22159 22160 } 22161 22162 // collinear or singular triangle 22163 if ( denom === 0 ) { 22164 22165 // arbitrary location outside of triangle? 22166 // not sure if this is the best idea, maybe should be returning undefined 22167 return target.set( - 2, - 1, - 1 ); 22168 22169 } 22170 22171 var invDenom = 1 / denom; 22172 var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; 22173 var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; 22174
22175 // barycentric coordinates must always sum to 1 22176 return target.set( 1 - u - v, v, u ); 22177 22178 }; 22179 22180 }(), 22181 22182 containsPoint: function () { 22183 22184 var v1 = new Vector3(); 22185 22186 return function containsPoint( point, a, b, c ) { 22187 22188 Triangle.getBarycoord( point, a, b, c, v1 ); 22189 22190 return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); 22191 22192 }; 22193 22194 }() 22195 22196 } ); 22197 22198 Object.assign( Triangle.prototype, { 22199 22200 set: function ( a, b, c ) { 22201 22202 this.a.copy( a ); 22203 this.b.copy( b ); 22204 this.c.copy( c ); 22205 22206 return this; 22207 22208 }, 22209 22210 setFromPointsAndIndices: function ( points, i0, i1, i2 ) { 22211 22212 this.a.copy( points[ i0 ] ); 22213 this.b.copy( points[ i1 ] ); 22214 this.c.copy( points[ i2 ] ); 22215 22216 return this; 22217 22218 }, 22219 22220 clone: function () { 22221 22222 return new this.constructor().copy( this ); 22223 22224 }, 22225 22226 copy: function ( triangle ) { 22227 22228 this.a.copy( triangle.a ); 22229 this.b.copy( triangle.b ); 22230 this.c.copy( triangle.c ); 22231 22232 return this; 22233 22234 }, 22235 22236 getArea: function () { 22237 22238 var v0 = new Vector3(); 22239 var v1 = new Vector3(); 22240 22241 return function getArea() { 22242 22243 v0.subVectors( this.c, this.b ); 22244 v1.subVectors( this.a, this.b ); 22245 22246 return v0.cross( v1 ).length() * 0.5; 22247 22248 }; 22249 22250 }(), 22251 22252 getMidpoint: function ( target ) { 22253 22254 if ( target === undefined ) { 22255 22256 console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); 22257 target = new Vector3(); 22258 22259 } 22260 22261 return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); 22262 22263 }, 22264 22265 getNormal: function ( target ) { 22266 22267 return Triangle.getNormal( this.a, this.b, this.c, target ); 22268 22269 }, 22270 22271 getPlane: function ( target ) { 22272 22273 if ( target === undefined ) { 22274 22275 console.warn( 'THREE.Triangle: .getPlane() target is now required' ); 22276 target = new Vector3(); 22277 22278 } 22279 22280 return target.setFromCoplanarPoints( this.a, this.b, this.c ); 22281 22282 }, 22283 22284 getBarycoord: function ( point, target ) { 22285 22286 return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); 22287 22288 }, 22289 22290 containsPoint: function ( point ) { 22291 22292 return Triangle.containsPoint( point, this.a, this.b, this.c ); 22293 22294 }, 22295 22296 intersectsBox: function ( box ) { 22297 22298 return box.intersectsTriangle( this ); 22299 22300 }, 22301 22302 closestPointToPoint: function () { 22303 22304 var plane = new Plane(); 22305 var edgeList = [ new Line3(), new Line3(), new Line3() ]; 22306 var projectedPoint = new Vector3(); 22307 var closestPoint = new Vector3(); 22308 22309 return function closestPointToPoint( point, target ) { 22310 22311 if ( target === undefined ) { 22312 22313 console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); 22314 target = new Vector3(); 22315 22316 } 22317 22318 var minDistance = Infinity; 22319 22320 // project the point onto the plane of the triangle 22321 22322 plane.setFromCoplanarPoints( this.a, this.b, this.c ); 22323 plane.projectPoint( point, projectedPoint ); 22324 22325 // check if the projection lies within the triangle 22326 22327 if ( this.containsPoint( projectedPoint ) === true ) { 22328 22329 // if so, this is the closest point 22330 22331 target.copy( projectedPoint ); 22332 22333 } else { 22334 22335 // if not, the point falls outside the triangle. the target is the closest point to the triangle's edges or vertices 22336 22337 edgeList[ 0 ].set( this.a, this.b ); 22338 edgeList[ 1 ].set( this.b, this.c ); 22339 edgeList[ 2 ].set( this.c, this.a ); 22340 22341 for ( var i = 0; i < edgeList.length; i ++ ) { 22342 22343 edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint ); 22344 22345 var distance = projectedPoint.distanceToSquared( closestPoint ); 22346 22347 if ( distance < minDistance ) { 22348 22349 minDistance = distance; 22350 22351 target.copy( closestPoint ); 22352 22353 } 22354 22355 } 22356 22357 } 22358 22359 return target; 22360 22361 }; 22362 22363 }(), 22364 22365 equals: function ( triangle ) { 22366 22367 return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); 22368 22369 } 22370 22371 } ); 22372 22373 /** 22374 * @author mrdoob / http://mrdoob.com/ 22375 * @author alteredq / http://alteredqualia.com/ 22376 * @author mikael emtinger / http://gomo.se/ 22377 * @author jonobr1 / http://jonobr1.com/ 22378 */ 22379 22380 function Mesh( geometry, material ) { 22381 22382 Object3D.call( this ); 22383 22384 this.type = 'Mesh'; 22385 22386 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 22387 this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); 22388 22389 this.drawMode = TrianglesDrawMode; 22390 22391 this.updateMorphTargets(); 22392 22393 } 22394 22395 Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { 22396 22397 constructor: Mesh, 22398 22399 isMesh: true, 22400 22401 setDrawMode: function ( value ) { 22402 22403 this.drawMode = value; 22404 22405 }, 22406
22407 copy: function ( source ) { 22408 22409 Object3D.prototype.copy.call( this, source ); 22410 22411 this.drawMode = source.drawMode; 22412 22413 if ( source.morphTargetInfluences !== undefined ) { 22414 22415 this.morphTargetInfluences = source.morphTargetInfluences.slice(); 22416 22417 } 22418 22419 if ( source.morphTargetDictionary !== undefined ) { 22420 22421 this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); 22422 22423 } 22424 22425 return this; 22426 22427 }, 22428 22429 updateMorphTargets: function () { 22430 22431 var geometry = this.geometry; 22432 var m, ml, name; 22433 22434 if ( geometry.isBufferGeometry ) { 22435 22436 var morphAttributes = geometry.morphAttributes; 22437 var keys = Object.keys( morphAttributes ); 22438 22439 if ( keys.length > 0 ) { 22440 22441 var morphAttribute = morphAttributes[ keys[ 0 ] ]; 22442 22443 if ( morphAttribute !== undefined ) { 22444 22445 this.morphTargetInfluences = []; 22446 this.morphTargetDictionary = {}; 22447 22448 for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { 22449 22450 name = morphAttribute[ m ].name || String( m ); 22451 22452 this.morphTargetInfluences.push( 0 ); 22453 this.morphTargetDictionary[ name ] = m; 22454 22455 } 22456 22457 } 22458 22459 } 22460 22461 } else { 22462 22463 var morphTargets = geometry.morphTargets; 22464 22465 if ( morphTargets !== undefined && morphTargets.length > 0 ) { 22466 22467 this.morphTargetInfluences = []; 22468 this.morphTargetDictionary = {}; 22469 22470 for ( m = 0, ml = morphTargets.length; m < ml; m ++ ) { 22471 22472 name = morphTargets[ m ].name || String( m ); 22473 22474 this.morphTargetInfluences.push( 0 ); 22475 this.morphTargetDictionary[ name ] = m; 22476 22477 } 22478 22479 } 22480 22481 } 22482 22483 }, 22484 22485 raycast: ( function () { 22486 22487 var inverseMatrix = new Matrix4(); 22488 var ray = new Ray(); 22489 var sphere = new Sphere(); 22490 22491 var vA = new Vector3(); 22492 var vB = new Vector3(); 22493 var vC = new Vector3(); 22494 22495 var tempA = new Vector3(); 22496 var tempB = new Vector3(); 22497 var tempC = new Vector3(); 22498 22499 var uvA = new Vector2(); 22500 var uvB = new Vector2(); 22501 var uvC = new Vector2(); 22502 22503 var barycoord = new Vector3(); 22504 22505 var intersectionPoint = new Vector3(); 22506 var intersectionPointWorld = new Vector3(); 22507 22508 function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) { 22509 22510 Triangle.getBarycoord( point, p1, p2, p3, barycoord ); 22511 22512 uv1.multiplyScalar( barycoord.x ); 22513 uv2.multiplyScalar( barycoord.y ); 22514 uv3.multiplyScalar( barycoord.z ); 22515 22516 uv1.add( uv2 ).add( uv3 ); 22517 22518 return uv1.clone(); 22519 22520 } 22521 22522 function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { 22523 22524 var intersect; 22525 22526 if ( material.side === BackSide ) { 22527 22528 intersect = ray.intersectTriangle( pC, pB, pA, true, point ); 22529 22530 } else { 22531 22532 intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); 22533 22534 } 22535 22536 if ( intersect === null ) return null; 22537 22538 intersectionPointWorld.copy( point ); 22539 intersectionPointWorld.applyMatrix4( object.matrixWorld ); 22540 22541 var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); 22542 22543 if ( distance < raycaster.near || distance > raycaster.far ) return null; 22544 22545 return { 22546 distance: distance, 22547 point: intersectionPointWorld.clone(), 22548 object: object 22549 }; 22550 22551 } 22552 22553 function checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) { 22554 22555 vA.fromBufferAttribute( position, a ); 22556 vB.fromBufferAttribute( position, b ); 22557 vC.fromBufferAttribute( position, c ); 22558 22559 var intersection = checkIntersection( object, object.material, raycaster, ray, vA, vB, vC, intersectionPoint ); 22560 22561 if ( intersection ) { 22562 22563 if ( uv ) { 22564 22565 uvA.fromBufferAttribute( uv, a ); 22566 uvB.fromBufferAttribute( uv, b ); 22567 uvC.fromBufferAttribute( uv, c ); 22568 22569 intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC ); 22570 22571 } 22572 22573 var face = new Face3( a, b, c ); 22574 Triangle.getNormal( vA, vB, vC, face.normal ); 22575 22576 intersection.face = face; 22577 22578 } 22579 22580 return intersection; 22581 22582 } 22583 22584 return function raycast( raycaster, intersects ) { 22585 22586 var geometry = this.geometry; 22587 var material = this.material; 22588 var matrixWorld = this.matrixWorld; 22589 22590 if ( material === undefined ) return; 22591 22592 // Checking boundingSphere distance to ray 22593 22594 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 22595 22596 sphere.copy( geometry.boundingSphere ); 22597 sphere.applyMatrix4( matrixWorld ); 22598 22599 if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; 22600 22601 // 22602 22603 inverseMatrix.getInverse( matrixWorld ); 22604 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 22605 22606 // Check boundingBox before continuing 22607 22608 if ( geometry.boundingBox !== null ) { 22609 22610 if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; 22611 22612 } 22613 22614 var intersection; 22615 22616 if ( geometry.isBufferGeometry ) { 22617 22618 var a, b, c; 22619 var index = geometry.index; 22620 var position = geometry.attributes.position; 22621 var uv = geometry.attributes.uv; 22622 var i, l; 22623 22624 if ( index !== null ) { 22625 22626 // indexed buffer geometry 22627 22628 for ( i = 0, l = index.count; i < l; i += 3 ) { 22629 22630 a = index.getX( i ); 22631 b = index.getX( i + 1 ); 22632 c = index.getX( i + 2 ); 22633 22634 intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c ); 22635 22636 if ( intersection ) { 22637 22638 intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics 22639 intersects.push( intersection ); 22640 22641 } 22642 22643 } 22644 22645 } else if ( position !== undefined ) { 22646 22647 // non-indexed buffer geometry 22648 22649 for ( i = 0, l = position.count; i < l; i += 3 ) { 22650 22651 a = i; 22652 b = i + 1; 22653 c = i + 2; 22654 22655 intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c ); 22656 22657 if ( intersection ) { 22658 22659 intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics 22660 intersects.push( intersection ); 22661 22662 } 22663 22664 } 22665 22666 } 22667 22668 } else if ( geometry.isGeometry ) { 22669 22670 var fvA, fvB, fvC; 22671 var isMultiMaterial = Array.isArray( material ); 22672 22673 var vertices = geometry.vertices; 22674 var faces = geometry.faces; 22675 var uvs; 22676 22677 var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; 22678 if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; 22679 22680 for ( var f = 0, fl = faces.length; f < fl; f ++ ) { 22681 22682 var face = faces[ f ]; 22683 var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; 22684 22685 if ( faceMaterial === undefined ) continue; 22686 22687 fvA = vertices[ face.a ]; 22688 fvB = vertices[ face.b ]; 22689 fvC = vertices[ face.c ]; 22690 22691 if ( faceMaterial.morphTargets === true ) { 22692 22693 var morphTargets = geometry.morphTargets; 22694 var morphInfluences = this.morphTargetInfluences; 22695 22696 vA.set( 0, 0, 0 ); 22697 vB.set( 0, 0, 0 ); 22698 vC.set( 0, 0, 0 ); 22699 22700 for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { 22701 22702 var influence = morphInfluences[ t ]; 22703 22704 if ( influence === 0 ) continue; 22705 22706 var targets = morphTargets[ t ].vertices; 22707 22708 vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence ); 22709 vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence ); 22710 vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence ); 22711 22712 } 22713 22714 vA.add( fvA ); 22715 vB.add( fvB ); 22716 vC.add( fvC ); 22717 22718 fvA = vA; 22719 fvB = vB; 22720 fvC = vC; 22721 22722 } 22723 22724 intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); 22725 22726 if ( intersection ) { 22727 22728 if ( uvs && uvs[ f ] ) { 22729 22730 var uvs_f = uvs[ f ]; 22731 uvA.copy( uvs_f[ 0 ] ); 22732 uvB.copy( uvs_f[ 1 ] ); 22733 uvC.copy( uvs_f[ 2 ] ); 22734 22735 intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC ); 22736 22737 } 22738 22739 intersection.face = face; 22740 intersection.faceIndex = f; 22741 intersects.push( intersection ); 22742 22743 } 22744 22745 } 22746 22747 } 22748 22749 }; 22750 22751 }() ), 22752 22753 clone: function () { 22754 22755 return new this.constructor( this.geometry, this.material ).copy( this ); 22756 22757 } 22758 22759 } ); 22760 22761 /** 22762 * @author mrdoob / http://mrdoob.com/ 22763 */ 22764
22765 function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { 22766 22767 var clearColor = new Color( 0x000000 ); 22768 var clearAlpha = 0; 22769 22770 var planeCamera, planeMesh; 22771 var boxMesh; 22772 22773 function render( renderList, scene, camera, forceClear ) { 22774 22775 var background = scene.background; 22776 22777 if ( background === null ) { 22778 22779 setClear( clearColor, clearAlpha ); 22780 22781 } else if ( background && background.isColor ) { 22782 22783 setClear( background, 1 ); 22784 forceClear = true; 22785 22786 } 22787 22788 if ( renderer.autoClear || forceClear ) { 22789 22790 renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); 22791 22792 } 22793 22794 if ( background && background.isCubeTexture ) { 22795 22796 if ( boxMesh === undefined ) { 22797 22798 boxMesh = new Mesh( 22799 new BoxBufferGeometry( 1, 1, 1 ), 22800 new ShaderMaterial( { 22801 uniforms: ShaderLib.cube.uniforms, 22802 vertexShader: ShaderLib.cube.vertexShader, 22803 fragmentShader: ShaderLib.cube.fragmentShader, 22804 side: BackSide, 22805 depthTest: true, 22806 depthWrite: false, 22807 fog: false 22808 } ) 22809 ); 22810 22811 boxMesh.geometry.removeAttribute( 'normal' ); 22812 boxMesh.geometry.removeAttribute( 'uv' ); 22813 22814 boxMesh.onBeforeRender = function ( renderer, scene, camera ) { 22815 22816 this.matrixWorld.copyPosition( camera.matrixWorld ); 22817 22818 }; 22819 22820 objects.update( boxMesh ); 22821 22822 } 22823 22824 boxMesh.material.uniforms.tCube.value = background; 22825 22826 renderList.push( boxMesh, boxMesh.geometry, boxMesh.material, 0, null ); 22827 22828 } else if ( background && background.isTexture ) { 22829 22830 if ( planeCamera === undefined ) { 22831 22832 planeCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); 22833 22834 planeMesh = new Mesh( 22835 new PlaneBufferGeometry( 2, 2 ), 22836 new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } ) 22837 ); 22838 22839 objects.update( planeMesh ); 22840 22841 } 22842 22843 planeMesh.material.map = background; 22844 22845 // TODO Push this to renderList 22846 22847 renderer.renderBufferDirect( planeCamera, null, planeMesh.geometry, planeMesh.material, planeMesh, null ); 22848 22849 } 22850 22851 } 22852 22853 function setClear( color, alpha ) { 22854 22855 state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); 22856 22857 } 22858 22859 return { 22860 22861 getClearColor: function () { 22862 22863 return clearColor; 22864 22865 }, 22866 setClearColor: function ( color, alpha ) { 22867 22868 clearColor.set( color ); 22869 clearAlpha = alpha !== undefined ? alpha : 1; 22870 setClear( clearColor, clearAlpha ); 22871 22872 }, 22873 getClearAlpha: function () { 22874 22875 return clearAlpha; 22876 22877 }, 22878 setClearAlpha: function ( alpha ) { 22879 22880 clearAlpha = alpha; 22881 setClear( clearColor, clearAlpha ); 22882 22883 }, 22884 render: render 22885 22886 }; 22887 22888 } 22889 22890 /** 22891 * @author mrdoob / http://mrdoob.com/ 22892 */ 22893 22894 function WebGLBufferRenderer( gl, extensions, info ) { 22895 22896 var mode; 22897 22898 function setMode( value ) { 22899 22900 mode = value; 22901 22902 } 22903 22904 function render( start, count ) { 22905 22906 gl.drawArrays( mode, start, count ); 22907 22908 info.update( count, mode ); 22909 22910 } 22911 22912 function renderInstances( geometry, start, count ) { 22913 22914 var extension = extensions.get( 'ANGLE_instanced_arrays' ); 22915 22916 if ( extension === null ) { 22917 22918 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); 22919 return; 22920 22921 } 22922 22923 extension.drawArraysInstancedANGLE( mode, start, count, geometry.maxInstancedCount ); 22924 22925 info.update( count, mode, geometry.maxInstancedCount ); 22926 22927 } 22928 22929 // 22930 22931 this.setMode = setMode; 22932 this.render = render; 22933 this.renderInstances = renderInstances; 22934 22935 } 22936 22937 /** 22938 * @author mrdoob / http://mrdoob.com/ 22939 */ 22940 22941 function WebGLCapabilities( gl, extensions, parameters ) { 22942 22943 var maxAnisotropy; 22944 22945 function getMaxAnisotropy() { 22946 22947 if ( maxAnisotropy !== undefined ) return maxAnisotropy; 22948 22949 var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); 22950 22951 if ( extension !== null ) { 22952 22953 maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); 22954 22955 } else { 22956 22957 maxAnisotropy = 0; 22958 22959 } 22960 22961 return maxAnisotropy; 22962 22963 } 22964 22965 function getMaxPrecision( precision ) { 22966 22967 if ( precision === 'highp' ) { 22968 22969 if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && 22970 gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { 22971 22972 return 'highp'; 22973 22974 } 22975 22976 precision = 'mediump'; 22977 22978 } 22979 22980 if ( precision === 'mediump' ) { 22981 22982 if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && 22983 gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { 22984 22985 return 'mediump'; 22986 22987 } 22988 22989 } 22990 22991 return 'lowp'; 22992 22993 } 22994 22995 var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; 22996 var maxPrecision = getMaxPrecision( precision ); 22997 22998 if ( maxPrecision !== precision ) { 22999 23000 console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); 23001 precision = maxPrecision; 23002 23003 } 23004 23005 var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; 23006 23007 var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); 23008 var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); 23009 var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); 23010 var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); 23011 23012 var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); 23013 var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); 23014 var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); 23015 var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); 23016 23017 var vertexTextures = maxVertexTextures > 0; 23018 var floatFragmentTextures = !! extensions.get( 'OES_texture_float' ); 23019 var floatVertexTextures = vertexTextures && floatFragmentTextures; 23020 23021 return { 23022 23023 getMaxAnisotropy: getMaxAnisotropy, 23024 getMaxPrecision: getMaxPrecision,
vendor: 8,210 bytes, lines 23025-23416
23025 23026 precision: precision, 23027 logarithmicDepthBuffer: logarithmicDepthBuffer, 23028 23029 maxTextures: maxTextures, 23030 maxVertexTextures: maxVertexTextures, 23031 maxTextureSize: maxTextureSize, 23032 maxCubemapSize: maxCubemapSize, 23033 23034 maxAttributes: maxAttributes, 23035 maxVertexUniforms: maxVertexUniforms, 23036 maxVaryings: maxVaryings, 23037 maxFragmentUniforms: maxFragmentUniforms, 23038 23039 vertexTextures: vertexTextures, 23040 floatFragmentTextures: floatFragmentTextures, 23041 floatVertexTextures: floatVertexTextures 23042 23043 }; 23044 23045 } 23046 23047 /** 23048 * @author tschw 23049 */ 23050 23051 function WebGLClipping() { 23052 23053 var scope = this, 23054 23055 globalState = null, 23056 numGlobalPlanes = 0, 23057 localClippingEnabled = false, 23058 renderingShadows = false, 23059 23060 plane = new Plane(), 23061 viewNormalMatrix = new Matrix3(), 23062 23063 uniform = { value: null, needsUpdate: false }; 23064 23065 this.uniform = uniform; 23066 this.numPlanes = 0; 23067 this.numIntersection = 0; 23068 23069 this.init = function ( planes, enableLocalClipping, camera ) { 23070 23071 var enabled = 23072 planes.length !== 0 || 23073 enableLocalClipping || 23074 // enable state of previous frame - the clipping code has to 23075 // run another frame in order to reset the state: 23076 numGlobalPlanes !== 0 || 23077 localClippingEnabled; 23078 23079 localClippingEnabled = enableLocalClipping; 23080 23081 globalState = projectPlanes( planes, camera, 0 ); 23082 numGlobalPlanes = planes.length; 23083 23084 return enabled; 23085 23086 }; 23087 23088 this.beginShadows = function () { 23089 23090 renderingShadows = true; 23091 projectPlanes( null ); 23092 23093 }; 23094 23095 this.endShadows = function () { 23096 23097 renderingShadows = false; 23098 resetGlobalState(); 23099 23100 }; 23101 23102 this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { 23103 23104 if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { 23105 23106 // there's no local clipping 23107 23108 if ( renderingShadows ) { 23109 23110 // there's no global clipping 23111 23112 projectPlanes( null ); 23113 23114 } else { 23115 23116 resetGlobalState(); 23117 23118 } 23119 23120 } else { 23121 23122 var nGlobal = renderingShadows ? 0 : numGlobalPlanes, 23123 lGlobal = nGlobal * 4, 23124 23125 dstArray = cache.clippingState || null; 23126 23127 uniform.value = dstArray; // ensure unique state 23128 23129 dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); 23130 23131 for ( var i = 0; i !== lGlobal; ++ i ) { 23132 23133 dstArray[ i ] = globalState[ i ]; 23134 23135 } 23136 23137 cache.clippingState = dstArray; 23138 this.numIntersection = clipIntersection ? this.numPlanes : 0; 23139 this.numPlanes += nGlobal; 23140 23141 } 23142 23143 23144 }; 23145 23146 function resetGlobalState() { 23147 23148 if ( uniform.value !== globalState ) { 23149 23150 uniform.value = globalState; 23151 uniform.needsUpdate = numGlobalPlanes > 0; 23152 23153 } 23154 23155 scope.numPlanes = numGlobalPlanes; 23156 scope.numIntersection = 0; 23157 23158 } 23159 23160 function projectPlanes( planes, camera, dstOffset, skipTransform ) { 23161 23162 var nPlanes = planes !== null ? planes.length : 0, 23163 dstArray = null; 23164 23165 if ( nPlanes !== 0 ) { 23166 23167 dstArray = uniform.value; 23168 23169 if ( skipTransform !== true || dstArray === null ) { 23170 23171 var flatSize = dstOffset + nPlanes * 4, 23172 viewMatrix = camera.matrixWorldInverse; 23173 23174 viewNormalMatrix.getNormalMatrix( viewMatrix ); 23175 23176 if ( dstArray === null || dstArray.length < flatSize ) { 23177 23178 dstArray = new Float32Array( flatSize ); 23179 23180 } 23181 23182 for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { 23183 23184 plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); 23185 23186 plane.normal.toArray( dstArray, i4 ); 23187 dstArray[ i4 + 3 ] = plane.constant; 23188 23189 } 23190 23191 } 23192 23193 uniform.value = dstArray; 23194 uniform.needsUpdate = true; 23195 23196 } 23197 23198 scope.numPlanes = nPlanes; 23199 23200 return dstArray; 23201 23202 } 23203 23204 } 23205 23206 /** 23207 * @author mrdoob / http://mrdoob.com/ 23208 */ 23209 23210 function WebGLExtensions( gl ) { 23211 23212 var extensions = {}; 23213 23214 return { 23215 23216 get: function ( name ) { 23217 23218 if ( extensions[ name ] !== undefined ) { 23219 23220 return extensions[ name ]; 23221 23222 } 23223 23224 var extension; 23225 23226 switch ( name ) { 23227 23228 case 'WEBGL_depth_texture': 23229 extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); 23230 break; 23231 23232 case 'EXT_texture_filter_anisotropic': 23233 extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); 23234 break; 23235 23236 case 'WEBGL_compressed_texture_s3tc': 23237 extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); 23238 break; 23239 23240 case 'WEBGL_compressed_texture_pvrtc': 23241 extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); 23242 break; 23243 23244 default: 23245 extension = gl.getExtension( name ); 23246 23247 } 23248 23249 if ( extension === null ) { 23250 23251 console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); 23252 23253 } 23254 23255 extensions[ name ] = extension; 23256 23257 return extension; 23258 23259 } 23260 23261 }; 23262 23263 } 23264 23265 /** 23266 * @author mrdoob / http://mrdoob.com/ 23267 */ 23268 23269 function WebGLGeometries( gl, attributes, info ) { 23270 23271 var geometries = {}; 23272 var wireframeAttributes = {}; 23273 23274 function onGeometryDispose( event ) { 23275 23276 var geometry = event.target; 23277 var buffergeometry = geometries[ geometry.id ]; 23278 23279 if ( buffergeometry.index !== null ) { 23280 23281 attributes.remove( buffergeometry.index ); 23282 23283 } 23284 23285 for ( var name in buffergeometry.attributes ) { 23286 23287 attributes.remove( buffergeometry.attributes[ name ] ); 23288 23289 } 23290 23291 geometry.removeEventListener( 'dispose', onGeometryDispose ); 23292 23293 delete geometries[ geometry.id ]; 23294 23295 // TODO Remove duplicate code 23296 23297 var attribute = wireframeAttributes[ geometry.id ]; 23298 23299 if ( attribute ) { 23300 23301 attributes.remove( attribute ); 23302 delete wireframeAttributes[ geometry.id ]; 23303 23304 } 23305 23306 attribute = wireframeAttributes[ buffergeometry.id ]; 23307 23308 if ( attribute ) { 23309 23310 attributes.remove( attribute ); 23311 delete wireframeAttributes[ buffergeometry.id ]; 23312 23313 } 23314 23315 // 23316 23317 info.memory.geometries --; 23318 23319 } 23320 23321 function get( object, geometry ) { 23322 23323 var buffergeometry = geometries[ geometry.id ]; 23324 23325 if ( buffergeometry ) return buffergeometry; 23326 23327 geometry.addEventListener( 'dispose', onGeometryDispose ); 23328 23329 if ( geometry.isBufferGeometry ) { 23330 23331 buffergeometry = geometry; 23332 23333 } else if ( geometry.isGeometry ) { 23334 23335 if ( geometry._bufferGeometry === undefined ) { 23336 23337 geometry._bufferGeometry = new BufferGeometry().setFromObject( object ); 23338 23339 } 23340 23341 buffergeometry = geometry._bufferGeometry; 23342 23343 } 23344 23345 geometries[ geometry.id ] = buffergeometry; 23346 23347 info.memory.geometries ++; 23348 23349 return buffergeometry; 23350 23351 } 23352 23353 function update( geometry ) { 23354 23355 var index = geometry.index; 23356 var geometryAttributes = geometry.attributes; 23357 23358 if ( index !== null ) { 23359 23360 attributes.update( index, gl.ELEMENT_ARRAY_BUFFER ); 23361 23362 } 23363 23364 for ( var name in geometryAttributes ) { 23365 23366 attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER ); 23367 23368 } 23369 23370 // morph targets 23371 23372 var morphAttributes = geometry.morphAttributes; 23373 23374 for ( var name in morphAttributes ) { 23375 23376 var array = morphAttributes[ name ]; 23377 23378 for ( var i = 0, l = array.length; i < l; i ++ ) { 23379 23380 attributes.update( array[ i ], gl.ARRAY_BUFFER ); 23381 23382 } 23383 23384 } 23385 23386 } 23387 23388 function getWireframeAttribute( geometry ) { 23389 23390 var attribute = wireframeAttributes[ geometry.id ]; 23391 23392 if ( attribute ) return attribute; 23393 23394 var indices = []; 23395 23396 var geometryIndex = geometry.index; 23397 var geometryAttributes = geometry.attributes; 23398 23399 // console.time( 'wireframe' ); 23400 23401 if ( geometryIndex !== null ) { 23402 23403 var array = geometryIndex.array; 23404 23405 for ( var i = 0, l = array.length; i < l; i += 3 ) { 23406 23407 var a = array[ i + 0 ]; 23408 var b = array[ i + 1 ]; 23409 var c = array[ i + 2 ]; 23410 23411 indices.push( a, b, b, c, c, a ); 23412 23413 } 23414 23415 } else { 23416
23417 var array = geometryAttributes.position.array; 23418 23419 for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { 23420 23421 var a = i + 0; 23422 var b = i + 1; 23423 var c = i + 2; 23424 23425 indices.push( a, b, b, c, c, a ); 23426 23427 } 23428 23429 } 23430 23431 // console.timeEnd( 'wireframe' ); 23432 23433 attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); 23434 23435 attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER ); 23436 23437 wireframeAttributes[ geometry.id ] = attribute; 23438 23439 return attribute; 23440 23441 } 23442 23443 return { 23444 23445 get: get, 23446 update: update, 23447 23448 getWireframeAttribute: getWireframeAttribute 23449 23450 }; 23451 23452 } 23453 23454 /** 23455 * @author mrdoob / http://mrdoob.com/ 23456 */ 23457 23458 function WebGLIndexedBufferRenderer( gl, extensions, info ) { 23459 23460 var mode; 23461 23462 function setMode( value ) { 23463 23464 mode = value; 23465 23466 } 23467 23468 var type, bytesPerElement; 23469 23470 function setIndex( value ) { 23471 23472 type = value.type; 23473 bytesPerElement = value.bytesPerElement; 23474 23475 } 23476 23477 function render( start, count ) { 23478 23479 gl.drawElements( mode, count, type, start * bytesPerElement ); 23480 23481 info.update( count, mode ); 23482 23483 } 23484 23485 function renderInstances( geometry, start, count ) { 23486 23487 var extension = extensions.get( 'ANGLE_instanced_arrays' ); 23488 23489 if ( extension === null ) { 23490 23491 console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); 23492 return; 23493 23494 } 23495 23496 extension.drawElementsInstancedANGLE( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); 23497 23498 info.update( count, mode, geometry.maxInstancedCount ); 23499 23500 } 23501 23502 // 23503 23504 this.setMode = setMode; 23505 this.setIndex = setIndex; 23506 this.render = render; 23507 this.renderInstances = renderInstances; 23508 23509 } 23510 23511 /** 23512 * @author Mugen87 / https://github.com/Mugen87 23513 */ 23514 23515 function WebGLInfo( gl ) { 23516 23517 var memory = { 23518 geometries: 0, 23519 textures: 0 23520 }; 23521 23522 var render = { 23523 frame: 0, 23524 calls: 0, 23525 triangles: 0, 23526 points: 0, 23527 lines: 0 23528 }; 23529 23530 function update( count, mode, instanceCount ) { 23531 23532 instanceCount = instanceCount || 1; 23533 23534 render.calls ++; 23535 23536 switch ( mode ) { 23537 23538 case gl.TRIANGLES: 23539 render.triangles += instanceCount * ( count / 3 ); 23540 break; 23541 23542 case gl.TRIANGLE_STRIP: 23543 case gl.TRIANGLE_FAN: 23544 render.triangles += instanceCount * ( count - 2 ); 23545 break; 23546 23547 case gl.LINES: 23548 render.lines += instanceCount * ( count / 2 ); 23549 break; 23550 23551 case gl.LINE_STRIP: 23552 render.lines += instanceCount * ( count - 1 ); 23553 break; 23554 23555 case gl.LINE_LOOP: 23556 render.lines += instanceCount * count; 23557 break; 23558 23559 case gl.POINTS: 23560 render.points += instanceCount * count; 23561 break; 23562 23563 default: 23564 console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); 23565 break; 23566 23567 } 23568 23569 } 23570 23571 function reset() { 23572 23573 render.frame ++; 23574 render.calls = 0; 23575 render.triangles = 0; 23576 render.points = 0; 23577 render.lines = 0; 23578 23579 } 23580 23581 return { 23582 memory: memory, 23583 render: render, 23584 programs: null, 23585 autoReset: true, 23586 reset: reset, 23587 update: update 23588 }; 23589 23590 } 23591 23592 /** 23593 * @author mrdoob / http://mrdoob.com/ 23594 */ 23595 23596 function absNumericalSort( a, b ) { 23597 23598 return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); 23599 23600 } 23601 23602 function WebGLMorphtargets( gl ) { 23603 23604 var influencesList = {}; 23605 var morphInfluences = new Float32Array( 8 ); 23606 23607 function update( object, geometry, material, program ) { 23608 23609 var objectInfluences = object.morphTargetInfluences; 23610 23611 var length = objectInfluences.length; 23612 23613 var influences = influencesList[ geometry.id ]; 23614 23615 if ( influences === undefined ) { 23616 23617 // initialise list 23618 23619 influences = []; 23620 23621 for ( var i = 0; i < length; i ++ ) { 23622 23623 influences[ i ] = [ i, 0 ]; 23624 23625 } 23626 23627 influencesList[ geometry.id ] = influences; 23628 23629 } 23630 23631 var morphTargets = material.morphTargets && geometry.morphAttributes.position; 23632 var morphNormals = material.morphNormals && geometry.morphAttributes.normal; 23633 23634 // Remove current morphAttributes 23635 23636 for ( var i = 0; i < length; i ++ ) { 23637 23638 var influence = influences[ i ]; 23639 23640 if ( influence[ 1 ] !== 0 ) { 23641 23642 if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i ); 23643 if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i ); 23644 23645 } 23646 23647 } 23648 23649 // Collect influences 23650 23651 for ( var i = 0; i < length; i ++ ) { 23652 23653 var influence = influences[ i ]; 23654 23655 influence[ 0 ] = i; 23656 influence[ 1 ] = objectInfluences[ i ]; 23657 23658 } 23659 23660 influences.sort( absNumericalSort ); 23661 23662 // Add morphAttributes 23663 23664 for ( var i = 0; i < 8; i ++ ) { 23665 23666 var influence = influences[ i ]; 23667 23668 if ( influence ) { 23669 23670 var index = influence[ 0 ]; 23671 var value = influence[ 1 ]; 23672 23673 if ( value ) { 23674 23675 if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] ); 23676 if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] ); 23677 23678 morphInfluences[ i ] = value; 23679 continue; 23680 23681 } 23682 23683 } 23684 23685 morphInfluences[ i ] = 0; 23686 23687 } 23688 23689 program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); 23690 23691 } 23692 23693 return { 23694 23695 update: update 23696 23697 }; 23698 23699 } 23700 23701 /** 23702 * @author mrdoob / http://mrdoob.com/ 23703 */ 23704 23705 function WebGLObjects( geometries, info ) { 23706 23707 var updateList = {}; 23708 23709 function update( object ) { 23710 23711 var frame = info.render.frame; 23712 23713 var geometry = object.geometry; 23714 var buffergeometry = geometries.get( object, geometry ); 23715 23716 // Update once per frame 23717
vendor: 16,111 bytes, lines 23718-24548
23718 if ( updateList[ buffergeometry.id ] !== frame ) { 23719 23720 if ( geometry.isGeometry ) { 23721 23722 buffergeometry.updateFromObject( object ); 23723 23724 } 23725 23726 geometries.update( buffergeometry ); 23727 23728 updateList[ buffergeometry.id ] = frame; 23729 23730 } 23731 23732 return buffergeometry; 23733 23734 } 23735 23736 function dispose() { 23737 23738 updateList = {}; 23739 23740 } 23741 23742 return { 23743 23744 update: update, 23745 dispose: dispose 23746 23747 }; 23748 23749 } 23750 23751 /** 23752 * @author mrdoob / http://mrdoob.com/ 23753 */ 23754 23755 function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { 23756 23757 images = images !== undefined ? images : []; 23758 mapping = mapping !== undefined ? mapping : CubeReflectionMapping; 23759 23760 Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 23761 23762 this.flipY = false; 23763 23764 } 23765 23766 CubeTexture.prototype = Object.create( Texture.prototype ); 23767 CubeTexture.prototype.constructor = CubeTexture; 23768 23769 CubeTexture.prototype.isCubeTexture = true; 23770 23771 Object.defineProperty( CubeTexture.prototype, 'images', { 23772 23773 get: function () { 23774 23775 return this.image; 23776 23777 }, 23778 23779 set: function ( value ) { 23780 23781 this.image = value; 23782 23783 } 23784 23785 } ); 23786 23787 /** 23788 * @author tschw 23789 * 23790 * Uniforms of a program. 23791 * Those form a tree structure with a special top-level container for the root, 23792 * which you get by calling 'new WebGLUniforms( gl, program, renderer )'. 23793 * 23794 * 23795 * Properties of inner nodes including the top-level container: 23796 * 23797 * .seq - array of nested uniforms 23798 * .map - nested uniforms by name 23799 * 23800 * 23801 * Methods of all nodes except the top-level container: 23802 * 23803 * .setValue( gl, value, [renderer] ) 23804 * 23805 * uploads a uniform value(s) 23806 * the 'renderer' parameter is needed for sampler uniforms 23807 * 23808 * 23809 * Static methods of the top-level container (renderer factorizations): 23810 * 23811 * .upload( gl, seq, values, renderer ) 23812 * 23813 * sets uniforms in 'seq' to 'values[id].value' 23814 * 23815 * .seqWithValue( seq, values ) : filteredSeq 23816 * 23817 * filters 'seq' entries with corresponding entry in values 23818 * 23819 * 23820 * Methods of the top-level container (renderer factorizations): 23821 * 23822 * .setValue( gl, name, value ) 23823 * 23824 * sets uniform with name 'name' to 'value' 23825 * 23826 * .set( gl, obj, prop ) 23827 * 23828 * sets uniform from object and property with same name than uniform 23829 * 23830 * .setOptional( gl, obj, prop ) 23831 * 23832 * like .set for an optional property of the object 23833 * 23834 */ 23835 23836 var emptyTexture = new Texture(); 23837 var emptyCubeTexture = new CubeTexture(); 23838 23839 // --- Base for inner nodes (including the root) --- 23840 23841 function UniformContainer() { 23842 23843 this.seq = []; 23844 this.map = {}; 23845 23846 } 23847 23848 // --- Utilities --- 23849 23850 // Array Caches (provide typed arrays for temporary by size) 23851 23852 var arrayCacheF32 = []; 23853 var arrayCacheI32 = []; 23854 23855 // Float32Array caches used for uploading Matrix uniforms 23856 23857 var mat4array = new Float32Array( 16 ); 23858 var mat3array = new Float32Array( 9 ); 23859 var mat2array = new Float32Array( 4 ); 23860 23861 // Flattening for arrays of vectors and matrices 23862 23863 function flatten( array, nBlocks, blockSize ) { 23864 23865 var firstElem = array[ 0 ]; 23866 23867 if ( firstElem <= 0 || firstElem > 0 ) return array; 23868 // unoptimized: ! isNaN( firstElem ) 23869 // see http://jacksondunstan.com/articles/983 23870 23871 var n = nBlocks * blockSize, 23872 r = arrayCacheF32[ n ]; 23873 23874 if ( r === undefined ) { 23875 23876 r = new Float32Array( n ); 23877 arrayCacheF32[ n ] = r; 23878 23879 } 23880 23881 if ( nBlocks !== 0 ) { 23882 23883 firstElem.toArray( r, 0 ); 23884 23885 for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { 23886 23887 offset += blockSize; 23888 array[ i ].toArray( r, offset ); 23889 23890 } 23891 23892 } 23893 23894 return r; 23895 23896 } 23897 23898 function arraysEqual( a, b ) { 23899 23900 if ( a.length !== b.length ) return false; 23901 23902 for ( var i = 0, l = a.length; i < l; i ++ ) { 23903 23904 if ( a[ i ] !== b[ i ] ) return false; 23905 23906 } 23907 23908 return true; 23909 23910 } 23911 23912 function copyArray( a, b ) { 23913 23914 for ( var i = 0, l = b.length; i < l; i ++ ) { 23915 23916 a[ i ] = b[ i ]; 23917 23918 } 23919 23920 } 23921 23922 // Texture unit allocation 23923 23924 function allocTexUnits( renderer, n ) { 23925 23926 var r = arrayCacheI32[ n ]; 23927 23928 if ( r === undefined ) { 23929 23930 r = new Int32Array( n ); 23931 arrayCacheI32[ n ] = r; 23932 23933 } 23934 23935 for ( var i = 0; i !== n; ++ i ) 23936 r[ i ] = renderer.allocTextureUnit(); 23937 23938 return r; 23939 23940 } 23941 23942 // --- Setters --- 23943 23944 // Note: Defining these methods externally, because they come in a bunch 23945 // and this way their names minify. 23946 23947 // Single scalar 23948 23949 function setValue1f( gl, v ) { 23950 23951 var cache = this.cache; 23952 23953 if ( cache[ 0 ] === v ) return; 23954 23955 gl.uniform1f( this.addr, v ); 23956 23957 cache[ 0 ] = v; 23958 23959 } 23960 23961 function setValue1i( gl, v ) { 23962 23963 var cache = this.cache; 23964 23965 if ( cache[ 0 ] === v ) return; 23966 23967 gl.uniform1i( this.addr, v ); 23968 23969 cache[ 0 ] = v; 23970 23971 } 23972 23973 // Single float vector (from flat array or THREE.VectorN) 23974 23975 function setValue2fv( gl, v ) { 23976 23977 var cache = this.cache; 23978 23979 if ( v.x !== undefined ) { 23980 23981 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { 23982 23983 gl.uniform2f( this.addr, v.x, v.y ); 23984 23985 cache[ 0 ] = v.x; 23986 cache[ 1 ] = v.y; 23987 23988 } 23989 23990 } else { 23991 23992 if ( arraysEqual( cache, v ) ) return; 23993 23994 gl.uniform2fv( this.addr, v ); 23995 23996 copyArray( cache, v ); 23997 23998 } 23999 24000 } 24001 24002 function setValue3fv( gl, v ) { 24003 24004 var cache = this.cache; 24005 24006 if ( v.x !== undefined ) { 24007 24008 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { 24009 24010 gl.uniform3f( this.addr, v.x, v.y, v.z ); 24011 24012 cache[ 0 ] = v.x; 24013 cache[ 1 ] = v.y; 24014 cache[ 2 ] = v.z; 24015 24016 } 24017 24018 } else if ( v.r !== undefined ) { 24019 24020 if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { 24021 24022 gl.uniform3f( this.addr, v.r, v.g, v.b ); 24023 24024 cache[ 0 ] = v.r; 24025 cache[ 1 ] = v.g; 24026 cache[ 2 ] = v.b; 24027 24028 } 24029 24030 } else { 24031 24032 if ( arraysEqual( cache, v ) ) return; 24033 24034 gl.uniform3fv( this.addr, v ); 24035 24036 copyArray( cache, v ); 24037 24038 } 24039 24040 } 24041 24042 function setValue4fv( gl, v ) { 24043 24044 var cache = this.cache; 24045 24046 if ( v.x !== undefined ) { 24047 24048 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { 24049 24050 gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); 24051 24052 cache[ 0 ] = v.x; 24053 cache[ 1 ] = v.y; 24054 cache[ 2 ] = v.z; 24055 cache[ 3 ] = v.w; 24056 24057 } 24058 24059 } else { 24060 24061 if ( arraysEqual( cache, v ) ) return; 24062 24063 gl.uniform4fv( this.addr, v ); 24064 24065 copyArray( cache, v ); 24066 24067 } 24068 24069 } 24070 24071 // Single matrix (from flat array or MatrixN) 24072 24073 function setValue2fm( gl, v ) { 24074 24075 var cache = this.cache; 24076 var elements = v.elements; 24077 24078 if ( elements === undefined ) { 24079 24080 if ( arraysEqual( cache, v ) ) return; 24081 24082 gl.uniformMatrix2fv( this.addr, false, v ); 24083 24084 copyArray( cache, v ); 24085 24086 } else { 24087 24088 if ( arraysEqual( cache, elements ) ) return; 24089 24090 mat2array.set( elements ); 24091 24092 gl.uniformMatrix2fv( this.addr, false, mat2array ); 24093 24094 copyArray( cache, elements ); 24095 24096 } 24097 24098 } 24099 24100 function setValue3fm( gl, v ) { 24101 24102 var cache = this.cache; 24103 var elements = v.elements; 24104 24105 if ( elements === undefined ) { 24106 24107 if ( arraysEqual( cache, v ) ) return; 24108 24109 gl.uniformMatrix3fv( this.addr, false, v ); 24110 24111 copyArray( cache, v ); 24112 24113 } else { 24114 24115 if ( arraysEqual( cache, elements ) ) return; 24116 24117 mat3array.set( elements ); 24118 24119 gl.uniformMatrix3fv( this.addr, false, mat3array ); 24120 24121 copyArray( cache, elements ); 24122 24123 } 24124 24125 } 24126 24127 function setValue4fm( gl, v ) { 24128 24129 var cache = this.cache; 24130 var elements = v.elements; 24131 24132 if ( elements === undefined ) { 24133 24134 if ( arraysEqual( cache, v ) ) return; 24135 24136 gl.uniformMatrix4fv( this.addr, false, v ); 24137 24138 copyArray( cache, v ); 24139 24140 } else { 24141 24142 if ( arraysEqual( cache, elements ) ) return; 24143 24144 mat4array.set( elements ); 24145 24146 gl.uniformMatrix4fv( this.addr, false, mat4array ); 24147 24148 copyArray( cache, elements ); 24149 24150 } 24151 24152 } 24153 24154 // Single texture (2D / Cube) 24155 24156 function setValueT1( gl, v, renderer ) { 24157 24158 var cache = this.cache; 24159 var unit = renderer.allocTextureUnit(); 24160 24161 if ( cache[ 0 ] !== unit ) { 24162 24163 gl.uniform1i( this.addr, unit ); 24164 cache[ 0 ] = unit; 24165 24166 } 24167 24168 renderer.setTexture2D( v || emptyTexture, unit ); 24169 24170 } 24171 24172 function setValueT6( gl, v, renderer ) { 24173 24174 var cache = this.cache; 24175 var unit = renderer.allocTextureUnit(); 24176 24177 if ( cache[ 0 ] !== unit ) { 24178 24179 gl.uniform1i( this.addr, unit ); 24180 cache[ 0 ] = unit; 24181 24182 } 24183 24184 renderer.setTextureCube( v || emptyCubeTexture, unit ); 24185 24186 } 24187 24188 // Integer / Boolean vectors or arrays thereof (always flat arrays) 24189 24190 function setValue2iv( gl, v ) { 24191 24192 var cache = this.cache; 24193 24194 if ( arraysEqual( cache, v ) ) return; 24195 24196 gl.uniform2iv( this.addr, v ); 24197 24198 copyArray( cache, v ); 24199 24200 } 24201 24202 function setValue3iv( gl, v ) { 24203 24204 var cache = this.cache; 24205 24206 if ( arraysEqual( cache, v ) ) return; 24207 24208 gl.uniform3iv( this.addr, v ); 24209 24210 copyArray( cache, v ); 24211 24212 } 24213 24214 function setValue4iv( gl, v ) { 24215 24216 var cache = this.cache; 24217 24218 if ( arraysEqual( cache, v ) ) return; 24219 24220 gl.uniform4iv( this.addr, v ); 24221 24222 copyArray( cache, v ); 24223 24224 } 24225 24226 // Helper to pick the right setter for the singular case 24227 24228 function getSingularSetter( type ) { 24229 24230 switch ( type ) { 24231 24232 case 0x1406: return setValue1f; // FLOAT 24233 case 0x8b50: return setValue2fv; // _VEC2 24234 case 0x8b51: return setValue3fv; // _VEC3 24235 case 0x8b52: return setValue4fv; // _VEC4 24236 24237 case 0x8b5a: return setValue2fm; // _MAT2 24238 case 0x8b5b: return setValue3fm; // _MAT3 24239 case 0x8b5c: return setValue4fm; // _MAT4 24240 24241 case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES 24242 case 0x8b60: return setValueT6; // SAMPLER_CUBE 24243 24244 case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL 24245 case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 24246 case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 24247 case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 24248 24249 } 24250 24251 } 24252 24253 // Array of scalars 24254 24255 function setValue1fv( gl, v ) { 24256 24257 var cache = this.cache; 24258 24259 if ( arraysEqual( cache, v ) ) return; 24260 24261 gl.uniform1fv( this.addr, v ); 24262 24263 copyArray( cache, v ); 24264 24265 } 24266 function setValue1iv( gl, v ) { 24267 24268 var cache = this.cache; 24269 24270 if ( arraysEqual( cache, v ) ) return; 24271 24272 gl.uniform1iv( this.addr, v ); 24273 24274 copyArray( cache, v ); 24275 24276 } 24277 24278 // Array of vectors (flat or from THREE classes) 24279 24280 function setValueV2a( gl, v ) { 24281 24282 var cache = this.cache; 24283 var data = flatten( v, this.size, 2 ); 24284 24285 if ( arraysEqual( cache, data ) ) return; 24286 24287 gl.uniform2fv( this.addr, data ); 24288 24289 this.updateCache( data ); 24290 24291 } 24292 24293 function setValueV3a( gl, v ) { 24294 24295 var cache = this.cache; 24296 var data = flatten( v, this.size, 3 ); 24297 24298 if ( arraysEqual( cache, data ) ) return; 24299 24300 gl.uniform3fv( this.addr, data ); 24301 24302 this.updateCache( data ); 24303 24304 } 24305 24306 function setValueV4a( gl, v ) { 24307 24308 var cache = this.cache; 24309 var data = flatten( v, this.size, 4 ); 24310 24311 if ( arraysEqual( cache, data ) ) return; 24312 24313 gl.uniform4fv( this.addr, data ); 24314 24315 this.updateCache( data ); 24316 24317 } 24318 24319 // Array of matrices (flat or from THREE clases) 24320 24321 function setValueM2a( gl, v ) { 24322 24323 var cache = this.cache; 24324 var data = flatten( v, this.size, 4 ); 24325 24326 if ( arraysEqual( cache, data ) ) return; 24327 24328 gl.uniformMatrix2fv( this.addr, false, data ); 24329 24330 this.updateCache( data ); 24331 24332 } 24333 24334 function setValueM3a( gl, v ) { 24335 24336 var cache = this.cache; 24337 var data = flatten( v, this.size, 9 ); 24338 24339 if ( arraysEqual( cache, data ) ) return; 24340 24341 gl.uniformMatrix3fv( this.addr, false, data ); 24342 24343 this.updateCache( data ); 24344 24345 } 24346 24347 function setValueM4a( gl, v ) { 24348 24349 var cache = this.cache; 24350 var data = flatten( v, this.size, 16 ); 24351 24352 if ( arraysEqual( cache, data ) ) return; 24353 24354 gl.uniformMatrix4fv( this.addr, false, data ); 24355 24356 this.updateCache( data ); 24357 24358 } 24359 24360 // Array of textures (2D / Cube) 24361 24362 function setValueT1a( gl, v, renderer ) { 24363 24364 var cache = this.cache; 24365 var n = v.length; 24366 24367 var units = allocTexUnits( renderer, n ); 24368 24369 if ( arraysEqual( cache, units ) === false ) { 24370 24371 gl.uniform1iv( this.addr, units ); 24372 copyArray( cache, units ); 24373 24374 } 24375 24376 for ( var i = 0; i !== n; ++ i ) { 24377 24378 renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] ); 24379 24380 } 24381 24382 } 24383 24384 function setValueT6a( gl, v, renderer ) { 24385 24386 var cache = this.cache; 24387 var n = v.length; 24388 24389 var units = allocTexUnits( renderer, n ); 24390 24391 if ( arraysEqual( cache, units ) === false ) { 24392 24393 gl.uniform1iv( this.addr, units ); 24394 copyArray( cache, units ); 24395 24396 } 24397 24398 for ( var i = 0; i !== n; ++ i ) { 24399 24400 renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); 24401 24402 } 24403 24404 } 24405 24406 // Helper to pick the right setter for a pure (bottom-level) array 24407 24408 function getPureArraySetter( type ) { 24409 24410 switch ( type ) { 24411 24412 case 0x1406: return setValue1fv; // FLOAT 24413 case 0x8b50: return setValueV2a; // _VEC2 24414 case 0x8b51: return setValueV3a; // _VEC3 24415 case 0x8b52: return setValueV4a; // _VEC4 24416 24417 case 0x8b5a: return setValueM2a; // _MAT2 24418 case 0x8b5b: return setValueM3a; // _MAT3 24419 case 0x8b5c: return setValueM4a; // _MAT4 24420 24421 case 0x8b5e: return setValueT1a; // SAMPLER_2D 24422 case 0x8b60: return setValueT6a; // SAMPLER_CUBE 24423 24424 case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL 24425 case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 24426 case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 24427 case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 24428 24429 } 24430 24431 } 24432 24433 // --- Uniform Classes --- 24434 24435 function SingleUniform( id, activeInfo, addr ) { 24436 24437 this.id = id; 24438 this.addr = addr; 24439 this.cache = []; 24440 this.setValue = getSingularSetter( activeInfo.type ); 24441 24442 // this.path = activeInfo.name; // DEBUG 24443 24444 } 24445 24446 function PureArrayUniform( id, activeInfo, addr ) { 24447 24448 this.id = id; 24449 this.addr = addr; 24450 this.cache = []; 24451 this.size = activeInfo.size; 24452 this.setValue = getPureArraySetter( activeInfo.type ); 24453 24454 // this.path = activeInfo.name; // DEBUG 24455 24456 } 24457 24458 PureArrayUniform.prototype.updateCache = function ( data ) { 24459 24460 var cache = this.cache; 24461 24462 if ( data instanceof Float32Array && cache.length !== data.length ) { 24463 24464 this.cache = new Float32Array( data.length ); 24465 24466 } 24467 24468 copyArray( cache, data ); 24469 24470 }; 24471 24472 function StructuredUniform( id ) { 24473 24474 this.id = id; 24475 24476 UniformContainer.call( this ); // mix-in 24477 24478 } 24479 24480 StructuredUniform.prototype.setValue = function ( gl, value ) { 24481 24482 // Note: Don't need an extra 'renderer' parameter, since samplers 24483 // are not allowed in structured uniforms. 24484 24485 var seq = this.seq; 24486 24487 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 24488 24489 var u = seq[ i ]; 24490 u.setValue( gl, value[ u.id ] ); 24491 24492 } 24493 24494 }; 24495 24496 // --- Top-level --- 24497 24498 // Parser - builds up the property tree from the path strings 24499 24500 var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; 24501 24502 // extracts 24503 // - the identifier (member name or array index) 24504 // - followed by an optional right bracket (found when array index) 24505 // - followed by an optional left bracket or dot (type of subscript) 24506 // 24507 // Note: These portions can be read in a non-overlapping fashion and 24508 // allow straightforward parsing of the hierarchy that WebGL encodes 24509 // in the uniform names. 24510 24511 function addUniform( container, uniformObject ) { 24512 24513 container.seq.push( uniformObject ); 24514 container.map[ uniformObject.id ] = uniformObject; 24515 24516 } 24517 24518 function parseUniform( activeInfo, addr, container ) { 24519 24520 var path = activeInfo.name, 24521 pathLength = path.length; 24522 24523 // reset RegExp object, because of the early exit of a previous run 24524 RePathPart.lastIndex = 0; 24525 24526 while ( true ) { 24527 24528 var match = RePathPart.exec( path ), 24529 matchEnd = RePathPart.lastIndex, 24530 24531 id = match[ 1 ], 24532 idIsIndex = match[ 2 ] === ']', 24533 subscript = match[ 3 ]; 24534 24535 if ( idIsIndex ) id = id | 0; // convert to integer 24536 24537 if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { 24538 24539 // bare name or "pure" bottom-level array "[0]" suffix 24540 24541 addUniform( container, subscript === undefined ? 24542 new SingleUniform( id, activeInfo, addr ) : 24543 new PureArrayUniform( id, activeInfo, addr ) ); 24544 24545 break; 24546 24547 } else { 24548
24549 // step into inner node / create it in case it doesn't exist 24550 24551 var map = container.map, next = map[ id ]; 24552 24553 if ( next === undefined ) { 24554 24555 next = new StructuredUniform( id ); 24556 addUniform( container, next ); 24557 24558 } 24559 24560 container = next; 24561 24562 } 24563 24564 } 24565 24566 } 24567 24568 // Root Container 24569 24570 function WebGLUniforms( gl, program, renderer ) { 24571 24572 UniformContainer.call( this ); 24573 24574 this.renderer = renderer; 24575 24576 var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); 24577 24578 for ( var i = 0; i < n; ++ i ) { 24579 24580 var info = gl.getActiveUniform( program, i ), 24581 addr = gl.getUniformLocation( program, info.name ); 24582 24583 parseUniform( info, addr, this ); 24584 24585 } 24586 24587 } 24588 24589 WebGLUniforms.prototype.setValue = function ( gl, name, value ) { 24590 24591 var u = this.map[ name ]; 24592 24593 if ( u !== undefined ) u.setValue( gl, value, this.renderer ); 24594 24595 }; 24596 24597 WebGLUniforms.prototype.setOptional = function ( gl, object, name ) { 24598 24599 var v = object[ name ]; 24600 24601 if ( v !== undefined ) this.setValue( gl, name, v ); 24602 24603 }; 24604 24605 24606 // Static interface 24607 24608 WebGLUniforms.upload = function ( gl, seq, values, renderer ) { 24609 24610 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 24611 24612 var u = seq[ i ], 24613 v = values[ u.id ]; 24614 24615 if ( v.needsUpdate !== false ) { 24616 24617 // note: always updating when .needsUpdate is undefined 24618 u.setValue( gl, v.value, renderer ); 24619 24620 } 24621 24622 } 24623 24624 }; 24625 24626 WebGLUniforms.seqWithValue = function ( seq, values ) { 24627 24628 var r = []; 24629 24630 for ( var i = 0, n = seq.length; i !== n; ++ i ) { 24631 24632 var u = seq[ i ]; 24633 if ( u.id in values ) r.push( u ); 24634 24635 } 24636 24637 return r; 24638 24639 }; 24640 24641 /** 24642 * @author mrdoob / http://mrdoob.com/ 24643 */ 24644 24645 function addLineNumbers( string ) { 24646 24647 var lines = string.split( '\n' ); 24648 24649 for ( var i = 0; i < lines.length; i ++ ) { 24650 24651 lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; 24652 24653 } 24654 24655 return lines.join( '\n' ); 24656 24657 } 24658 24659 function WebGLShader( gl, type, string ) { 24660 24661 var shader = gl.createShader( type ); 24662 24663 gl.shaderSource( shader, string ); 24664 gl.compileShader( shader ); 24665 24666 if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { 24667 24668 console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); 24669 24670 } 24671 24672 if ( gl.getShaderInfoLog( shader ) !== '' ) { 24673 24674 console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); 24675 24676 } 24677 24678 // --enable-privileged-webgl-extension 24679 // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); 24680 24681 return shader; 24682 24683 } 24684 24685 /** 24686 * @author mrdoob / http://mrdoob.com/ 24687 */ 24688 24689 var programIdCount = 0; 24690 24691 function getEncodingComponents( encoding ) { 24692 24693 switch ( encoding ) { 24694 24695 case LinearEncoding: 24696 return [ 'Linear', '( value )' ]; 24697 case sRGBEncoding: 24698 return [ 'sRGB', '( value )' ]; 24699 case RGBEEncoding: 24700 return [ 'RGBE', '( value )' ]; 24701 case RGBM7Encoding: 24702 return [ 'RGBM', '( value, 7.0 )' ]; 24703 case RGBM16Encoding: 24704 return [ 'RGBM', '( value, 16.0 )' ]; 24705 case RGBDEncoding: 24706 return [ 'RGBD', '( value, 256.0 )' ]; 24707 case GammaEncoding: 24708 return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; 24709 default: 24710 throw new Error( 'unsupported encoding: ' + encoding ); 24711 24712 } 24713 24714 } 24715 24716 function getTexelDecodingFunction( functionName, encoding ) { 24717 24718 var components = getEncodingComponents( encoding ); 24719 return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }'; 24720 24721 } 24722 24723 function getTexelEncodingFunction( functionName, encoding ) { 24724 24725 var components = getEncodingComponents( encoding ); 24726 return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; 24727 24728 } 24729 24730 function getToneMappingFunction( functionName, toneMapping ) { 24731 24732 var toneMappingName; 24733 24734 switch ( toneMapping ) { 24735 24736 case LinearToneMapping: 24737 toneMappingName = 'Linear'; 24738 break; 24739 24740 case ReinhardToneMapping: 24741 toneMappingName = 'Reinhard'; 24742 break; 24743 24744 case Uncharted2ToneMapping: 24745 toneMappingName = 'Uncharted2'; 24746 break; 24747 24748 case CineonToneMapping: 24749 toneMappingName = 'OptimizedCineon'; 24750 break; 24751 24752 default: 24753 throw new Error( 'unsupported toneMapping: ' + toneMapping ); 24754 24755 } 24756 24757 return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; 24758 24759 } 24760 24761 function generateExtensions( extensions, parameters, rendererExtensions ) { 24762 24763 extensions = extensions || {}; 24764 24765 var chunks = [ 24766 ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', 24767 ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', 24768 ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', 24769 ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' 24770 ]; 24771 24772 return chunks.filter( filterEmptyLine ).join( '\n' ); 24773 24774 } 24775 24776 function generateDefines( defines ) { 24777 24778 var chunks = []; 24779 24780 for ( var name in defines ) { 24781 24782 var value = defines[ name ]; 24783 24784 if ( value === false ) continue; 24785 24786 chunks.push( '#define ' + name + ' ' + value ); 24787 24788 } 24789 24790 return chunks.join( '\n' ); 24791 24792 } 24793 24794 function fetchAttributeLocations( gl, program ) { 24795 24796 var attributes = {}; 24797 24798 var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES ); 24799 24800 for ( var i = 0; i < n; i ++ ) { 24801 24802 var info = gl.getActiveAttrib( program, i ); 24803 var name = info.name; 24804 24805 // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); 24806 24807 attributes[ name ] = gl.getAttribLocation( program, name ); 24808 24809 } 24810 24811 return attributes; 24812 24813 } 24814 24815 function filterEmptyLine( string ) { 24816 24817 return string !== ''; 24818 24819 } 24820 24821 function replaceLightNums( string, parameters ) { 24822 24823 return string 24824 .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
24825 .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) 24826 .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) 24827 .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) 24828 .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ); 24829 24830 } 24831 24832 function replaceClippingPlaneNums( string, parameters ) { 24833 24834 return string 24835 .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) 24836 .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); 24837 24838 } 24839 24840 function parseIncludes( string ) { 24841 24842 var pattern = /^[ \t]*#include +<([\w\d.]+)>/gm; 24843 24844 function replace( match, include ) { 24845 24846 var replace = ShaderChunk[ include ]; 24847 24848 if ( replace === undefined ) { 24849 24850 throw new Error( 'Can not resolve #include <' + include + '>' ); 24851 24852 } 24853 24854 return parseIncludes( replace ); 24855 24856 } 24857 24858 return string.replace( pattern, replace ); 24859 24860 } 24861 24862 function unrollLoops( string ) { 24863 24864 var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; 24865 24866 function replace( match, start, end, snippet ) { 24867 24868 var unroll = ''; 24869 24870 for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { 24871 24872 unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' ); 24873 24874 } 24875 24876 return unroll; 24877 24878 } 24879 24880 return string.replace( pattern, replace ); 24881 24882 } 24883 24884 function WebGLProgram( renderer, extensions, code, material, shader, parameters ) { 24885 24886 var gl = renderer.context; 24887 24888 var defines = material.defines; 24889 24890 var vertexShader = shader.vertexShader; 24891 var fragmentShader = shader.fragmentShader; 24892 24893 var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; 24894 24895 if ( parameters.shadowMapType === PCFShadowMap ) { 24896 24897 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; 24898 24899 } else if ( parameters.shadowMapType === PCFSoftShadowMap ) { 24900 24901 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; 24902 24903 } 24904 24905 var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 24906 var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; 24907 var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; 24908 24909 if ( parameters.envMap ) { 24910 24911 switch ( material.envMap.mapping ) { 24912 24913 case CubeReflectionMapping: 24914 case CubeRefractionMapping: 24915 envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; 24916 break; 24917 24918 case CubeUVReflectionMapping: 24919 case CubeUVRefractionMapping: 24920 envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; 24921 break; 24922 24923 case EquirectangularReflectionMapping: 24924 case EquirectangularRefractionMapping: 24925 envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; 24926 break; 24927 24928 case SphericalReflectionMapping: 24929 envMapTypeDefine = 'ENVMAP_TYPE_SPHERE'; 24930 break; 24931 24932 } 24933 24934 switch ( material.envMap.mapping ) { 24935 24936 case CubeRefractionMapping: 24937 case EquirectangularRefractionMapping: 24938 envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; 24939 break; 24940 24941 } 24942 24943 switch ( material.combine ) { 24944 24945 case MultiplyOperation: 24946 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; 24947 break; 24948 24949 case MixOperation: 24950 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; 24951 break; 24952 24953 case AddOperation: 24954 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; 24955 break; 24956 24957 } 24958 24959 } 24960 24961 var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; 24962 24963 // console.log( 'building new program ' ); 24964 24965 // 24966 24967 var customExtensions = generateExtensions( material.extensions, parameters, extensions ); 24968 24969 var customDefines = generateDefines( defines ); 24970 24971 // 24972 24973 var program = gl.createProgram(); 24974 24975 var prefixVertex, prefixFragment; 24976 24977 if ( material.isRawShaderMaterial ) { 24978 24979 prefixVertex = [ 24980 24981 customDefines 24982 24983 ].filter( filterEmptyLine ).join( '\n' ); 24984 24985 if ( prefixVertex.length > 0 ) { 24986 24987 prefixVertex += '\n'; 24988 24989 } 24990 24991 prefixFragment = [ 24992 24993 customExtensions, 24994 customDefines 24995 24996 ].filter( filterEmptyLine ).join( '\n' ); 24997 24998 if ( prefixFragment.length > 0 ) { 24999 25000 prefixFragment += '\n'; 25001 25002 } 25003 25004 } else { 25005 25006 prefixVertex = [ 25007 25008 'precision ' + parameters.precision + ' float;', 25009 'precision ' + parameters.precision + ' int;', 25010 25011 '#define SHADER_NAME ' + shader.name, 25012 25013 customDefines, 25014 25015 parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', 25016 25017 '#define GAMMA_FACTOR ' + gammaFactorDefine, 25018 25019 '#define MAX_BONES ' + parameters.maxBones, 25020 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', 25021 ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', 25022 25023 parameters.map ? '#define USE_MAP' : '', 25024 parameters.envMap ? '#define USE_ENVMAP' : '', 25025 parameters.envMap ? '#define ' + envMapModeDefine : '', 25026 parameters.lightMap ? '#define USE_LIGHTMAP' : '', 25027 parameters.aoMap ? '#define USE_AOMAP' : '', 25028 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', 25029 parameters.bumpMap ? '#define USE_BUMPMAP' : '', 25030 parameters.normalMap ? '#define USE_NORMALMAP' : '', 25031 parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', 25032 parameters.specularMap ? '#define USE_SPECULARMAP' : '', 25033 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', 25034 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', 25035 parameters.alphaMap ? '#define USE_ALPHAMAP' : '', 25036 parameters.vertexColors ? '#define USE_COLOR' : '', 25037 25038 parameters.flatShading ? '#define FLAT_SHADED' : '', 25039 25040 parameters.skinning ? '#define USE_SKINNING' : '', 25041 parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', 25042 25043 parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', 25044 parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', 25045 parameters.doubleSided ? '#define DOUBLE_SIDED' : '', 25046 parameters.flipSided ? '#define FLIP_SIDED' : '', 25047 25048 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', 25049 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', 25050 25051 parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', 25052 25053 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', 25054 parameters.logarithmicDepthBuffer && extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 25055 25056 'uniform mat4 modelMatrix;', 25057 'uniform mat4 modelViewMatrix;', 25058 'uniform mat4 projectionMatrix;', 25059 'uniform mat4 viewMatrix;', 25060 'uniform mat3 normalMatrix;', 25061 'uniform vec3 cameraPosition;', 25062 25063 'attribute vec3 position;', 25064 'attribute vec3 normal;', 25065 'attribute vec2 uv;', 25066 25067 '#ifdef USE_COLOR', 25068 25069 ' attribute vec3 color;', 25070 25071 '#endif', 25072 25073 '#ifdef USE_MORPHTARGETS', 25074 25075 ' attribute vec3 morphTarget0;', 25076 ' attribute vec3 morphTarget1;', 25077 ' attribute vec3 morphTarget2;', 25078 ' attribute vec3 morphTarget3;', 25079 25080 ' #ifdef USE_MORPHNORMALS', 25081 25082 ' attribute vec3 morphNormal0;', 25083 ' attribute vec3 morphNormal1;', 25084 ' attribute vec3 morphNormal2;', 25085 ' attribute vec3 morphNormal3;', 25086 25087 ' #else', 25088 25089 ' attribute vec3 morphTarget4;', 25090 ' attribute vec3 morphTarget5;', 25091 ' attribute vec3 morphTarget6;', 25092 ' attribute vec3 morphTarget7;', 25093 25094 ' #endif', 25095 25096 '#endif', 25097 25098 '#ifdef USE_SKINNING', 25099 25100 ' attribute vec4 skinIndex;', 25101 ' attribute vec4 skinWeight;', 25102 25103 '#endif', 25104 25105 '\n' 25106 25107 ].filter( filterEmptyLine ).join( '\n' ); 25108 25109 prefixFragment = [ 25110 25111 customExtensions, 25112 25113 'precision ' + parameters.precision + ' float;', 25114 'precision ' + parameters.precision + ' int;', 25115 25116 '#define SHADER_NAME ' + shader.name, 25117 25118 customDefines, 25119 25120 parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer 25121 25122 '#define GAMMA_FACTOR ' + gammaFactorDefine, 25123 25124 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', 25125 ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', 25126 25127 parameters.map ? '#define USE_MAP' : '', 25128 parameters.envMap ? '#define USE_ENVMAP' : '', 25129 parameters.envMap ? '#define ' + envMapTypeDefine : '', 25130 parameters.envMap ? '#define ' + envMapModeDefine : '', 25131 parameters.envMap ? '#define ' + envMapBlendingDefine : '', 25132 parameters.lightMap ? '#define USE_LIGHTMAP' : '', 25133 parameters.aoMap ? '#define USE_AOMAP' : '', 25134 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', 25135 parameters.bumpMap ? '#define USE_BUMPMAP' : '', 25136 parameters.normalMap ? '#define USE_NORMALMAP' : '', 25137 parameters.specularMap ? '#define USE_SPECULARMAP' : '', 25138 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', 25139 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', 25140 parameters.alphaMap ? '#define USE_ALPHAMAP' : '', 25141 parameters.vertexColors ? '#define USE_COLOR' : '', 25142 25143 parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', 25144 25145 parameters.flatShading ? '#define FLAT_SHADED' : '', 25146 25147 parameters.doubleSided ? '#define DOUBLE_SIDED' : '', 25148 parameters.flipSided ? '#define FLIP_SIDED' : '', 25149 25150 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', 25151 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', 25152 25153 parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', 25154 25155 parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', 25156 25157 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', 25158 parameters.logarithmicDepthBuffer && extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 25159 25160 parameters.envMap && extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '', 25161 25162 'uniform mat4 viewMatrix;', 25163 'uniform vec3 cameraPosition;', 25164 25165 ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', 25166 ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below 25167 ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', 25168 25169 parameters.dithering ? '#define DITHERING' : '', 25170 25171 ( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below 25172 parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', 25173 parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', 25174 parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', 25175 parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', 25176 25177 parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '', 25178 25179 '\n' 25180 25181 ].filter( filterEmptyLine ).join( '\n' ); 25182 25183 } 25184 25185 vertexShader = parseIncludes( vertexShader ); 25186 vertexShader = replaceLightNums( vertexShader, parameters ); 25187 vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); 25188 25189 fragmentShader = parseIncludes( fragmentShader ); 25190 fragmentShader = replaceLightNums( fragmentShader, parameters ); 25191 fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); 25192 25193 vertexShader = unrollLoops( vertexShader ); 25194 fragmentShader = unrollLoops( fragmentShader ); 25195 25196 var vertexGlsl = prefixVertex + vertexShader; 25197 var fragmentGlsl = prefixFragment + fragmentShader; 25198 25199 // console.log( '*VERTEX*', vertexGlsl ); 25200 // console.log( '*FRAGMENT*', fragmentGlsl ); 25201 25202 var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl ); 25203 var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl ); 25204 25205 gl.attachShader( program, glVertexShader ); 25206 gl.attachShader( program, glFragmentShader ); 25207 25208 // Force a particular attribute to index 0. 25209 25210 if ( material.index0AttributeName !== undefined ) { 25211 25212 gl.bindAttribLocation( program, 0, material.index0AttributeName ); 25213 25214 } else if ( parameters.morphTargets === true ) { 25215 25216 // programs with morphTargets displace position out of attribute 0 25217 gl.bindAttribLocation( program, 0, 'position' ); 25218 25219 } 25220 25221 gl.linkProgram( program ); 25222 25223 var programLog = gl.getProgramInfoLog( program ).trim(); 25224 var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); 25225 var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); 25226 25227 var runnable = true; 25228 var haveDiagnostics = true; 25229 25230 // console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); 25231 // console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); 25232 25233 if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) { 25234 25235 runnable = false;
vendor: 4,320 bytes, lines 25236-25421
25236 25237 console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog ); 25238 25239 } else if ( programLog !== '' ) { 25240 25241 console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog ); 25242 25243 } else if ( vertexLog === '' || fragmentLog === '' ) { 25244 25245 haveDiagnostics = false; 25246 25247 } 25248 25249 if ( haveDiagnostics ) { 25250 25251 this.diagnostics = { 25252 25253 runnable: runnable, 25254 material: material, 25255 25256 programLog: programLog, 25257 25258 vertexShader: { 25259 25260 log: vertexLog, 25261 prefix: prefixVertex 25262 25263 }, 25264 25265 fragmentShader: { 25266 25267 log: fragmentLog, 25268 prefix: prefixFragment 25269 25270 } 25271 25272 }; 25273 25274 } 25275 25276 // clean up 25277 25278 gl.deleteShader( glVertexShader ); 25279 gl.deleteShader( glFragmentShader ); 25280 25281 // set up caching for uniform locations 25282 25283 var cachedUniforms; 25284 25285 this.getUniforms = function () { 25286 25287 if ( cachedUniforms === undefined ) { 25288 25289 cachedUniforms = new WebGLUniforms( gl, program, renderer ); 25290 25291 } 25292 25293 return cachedUniforms; 25294 25295 }; 25296 25297 // set up caching for attribute locations 25298 25299 var cachedAttributes; 25300 25301 this.getAttributes = function () { 25302 25303 if ( cachedAttributes === undefined ) { 25304 25305 cachedAttributes = fetchAttributeLocations( gl, program ); 25306 25307 } 25308 25309 return cachedAttributes; 25310 25311 }; 25312 25313 // free resource 25314 25315 this.destroy = function () { 25316 25317 gl.deleteProgram( program ); 25318 this.program = undefined; 25319 25320 }; 25321 25322 // DEPRECATED 25323 25324 Object.defineProperties( this, { 25325 25326 uniforms: { 25327 get: function () { 25328 25329 console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' ); 25330 return this.getUniforms(); 25331 25332 } 25333 }, 25334 25335 attributes: { 25336 get: function () { 25337 25338 console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' ); 25339 return this.getAttributes(); 25340 25341 } 25342 } 25343 25344 } ); 25345 25346 25347 // 25348 25349 this.name = shader.name; 25350 this.id = programIdCount ++; 25351 this.code = code; 25352 this.usedTimes = 1; 25353 this.program = program; 25354 this.vertexShader = glVertexShader; 25355 this.fragmentShader = glFragmentShader; 25356 25357 return this; 25358 25359 } 25360 25361 /** 25362 * @author mrdoob / http://mrdoob.com/ 25363 */ 25364 25365 function WebGLPrograms( renderer, extensions, capabilities ) { 25366 25367 var programs = []; 25368 25369 var shaderIDs = { 25370 MeshDepthMaterial: 'depth', 25371 MeshDistanceMaterial: 'distanceRGBA', 25372 MeshNormalMaterial: 'normal', 25373 MeshBasicMaterial: 'basic', 25374 MeshLambertMaterial: 'lambert', 25375 MeshPhongMaterial: 'phong', 25376 MeshToonMaterial: 'phong', 25377 MeshStandardMaterial: 'physical', 25378 MeshPhysicalMaterial: 'physical', 25379 LineBasicMaterial: 'basic', 25380 LineDashedMaterial: 'dashed', 25381 PointsMaterial: 'points', 25382 ShadowMaterial: 'shadow' 25383 }; 25384 25385 var parameterNames = [ 25386 "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", 25387 "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap", 25388 "roughnessMap", "metalnessMap", "gradientMap", 25389 "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", 25390 "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", 25391 "maxBones", "useVertexTexture", "morphTargets", "morphNormals", 25392 "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", 25393 "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", 25394 "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', 25395 "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" 25396 ]; 25397 25398 25399 function allocateBones( object ) { 25400 25401 var skeleton = object.skeleton; 25402 var bones = skeleton.bones; 25403 25404 if ( capabilities.floatVertexTextures ) { 25405 25406 return 1024; 25407 25408 } else { 25409 25410 // default for when object is not specified 25411 // ( for example when prebuilding shader to be used with multiple objects ) 25412 // 25413 // - leave some extra space for other uniforms 25414 // - limit here is ANGLE's 254 max uniform vectors 25415 // (up to 54 should be safe) 25416 25417 var nVertexUniforms = capabilities.maxVertexUniforms; 25418 var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); 25419 25420 var maxBones = Math.min( nVertexMatrices, bones.length ); 25421
25422 if ( maxBones < bones.length ) { 25423 25424 console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' ); 25425 return 0; 25426 25427 } 25428 25429 return maxBones; 25430 25431 } 25432 25433 } 25434 25435 function getTextureEncodingFromMap( map, gammaOverrideLinear ) { 25436 25437 var encoding; 25438 25439 if ( ! map ) { 25440 25441 encoding = LinearEncoding; 25442 25443 } else if ( map.isTexture ) { 25444 25445 encoding = map.encoding; 25446 25447 } else if ( map.isWebGLRenderTarget ) { 25448 25449 console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); 25450 encoding = map.texture.encoding; 25451 25452 } 25453 25454 // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. 25455 if ( encoding === LinearEncoding && gammaOverrideLinear ) { 25456 25457 encoding = GammaEncoding; 25458 25459 } 25460 25461 return encoding; 25462 25463 } 25464 25465 this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) { 25466 25467 var shaderID = shaderIDs[ material.type ]; 25468 25469 // heuristics to create shader parameters according to lights in the scene 25470 // (not to blow over maxLights budget) 25471 25472 var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; 25473 var precision = capabilities.precision; 25474 25475 if ( material.precision !== null ) { 25476 25477 precision = capabilities.getMaxPrecision( material.precision ); 25478 25479 if ( precision !== material.precision ) { 25480 25481 console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); 25482 25483 } 25484 25485 } 25486 25487 var currentRenderTarget = renderer.getRenderTarget(); 25488 25489 var parameters = { 25490 25491 shaderID: shaderID, 25492 25493 precision: precision, 25494 supportsVertexTextures: capabilities.vertexTextures, 25495 outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), 25496 map: !! material.map, 25497 mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), 25498 envMap: !! material.envMap, 25499 envMapMode: material.envMap && material.envMap.mapping, 25500 envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), 25501 envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ), 25502 lightMap: !! material.lightMap, 25503 aoMap: !! material.aoMap, 25504 emissiveMap: !! material.emissiveMap, 25505 emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), 25506 bumpMap: !! material.bumpMap, 25507 normalMap: !! material.normalMap, 25508 displacementMap: !! material.displacementMap, 25509 roughnessMap: !! material.roughnessMap, 25510 metalnessMap: !! material.metalnessMap, 25511 specularMap: !! material.specularMap, 25512 alphaMap: !! material.alphaMap, 25513 25514 gradientMap: !! material.gradientMap, 25515 25516 combine: material.combine, 25517 25518 vertexColors: material.vertexColors, 25519 25520 fog: !! fog, 25521 useFog: material.fog, 25522 fogExp: ( fog && fog.isFogExp2 ), 25523 25524 flatShading: material.flatShading, 25525 25526 sizeAttenuation: material.sizeAttenuation, 25527 logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, 25528 25529 skinning: material.skinning && maxBones > 0, 25530 maxBones: maxBones, 25531 useVertexTexture: capabilities.floatVertexTextures, 25532 25533 morphTargets: material.morphTargets, 25534 morphNormals: material.morphNormals, 25535 maxMorphTargets: renderer.maxMorphTargets, 25536 maxMorphNormals: renderer.maxMorphNormals, 25537 25538 numDirLights: lights.directional.length, 25539 numPointLights: lights.point.length, 25540 numSpotLights: lights.spot.length, 25541 numRectAreaLights: lights.rectArea.length, 25542 numHemiLights: lights.hemi.length, 25543 25544 numClippingPlanes: nClipPlanes, 25545 numClipIntersection: nClipIntersection, 25546 25547 dithering: material.dithering, 25548 25549 shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, 25550 shadowMapType: renderer.shadowMap.type, 25551 25552 toneMapping: renderer.toneMapping, 25553 physicallyCorrectLights: renderer.physicallyCorrectLights, 25554 25555 premultipliedAlpha: material.premultipliedAlpha, 25556 25557 alphaTest: material.alphaTest, 25558 doubleSided: material.side === DoubleSide, 25559 flipSided: material.side === BackSide, 25560 25561 depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false 25562 25563 }; 25564 25565 return parameters; 25566 25567 }; 25568 25569 this.getProgramCode = function ( material, parameters ) { 25570 25571 var array = []; 25572 25573 if ( parameters.shaderID ) { 25574 25575 array.push( parameters.shaderID ); 25576 25577 } else { 25578
25579 array.push( material.fragmentShader ); 25580 array.push( material.vertexShader ); 25581 25582 } 25583 25584 if ( material.defines !== undefined ) { 25585 25586 for ( var name in material.defines ) { 25587 25588 array.push( name ); 25589 array.push( material.defines[ name ] ); 25590 25591 } 25592 25593 } 25594 25595 for ( var i = 0; i < parameterNames.length; i ++ ) { 25596 25597 array.push( parameters[ parameterNames[ i ] ] ); 25598 25599 } 25600 25601 array.push( material.onBeforeCompile.toString() ); 25602 25603 array.push( renderer.gammaOutput ); 25604 25605 return array.join(); 25606 25607 }; 25608 25609 this.acquireProgram = function ( material, shader, parameters, code ) { 25610 25611 var program; 25612 25613 // Check if code has been already compiled 25614 for ( var p = 0, pl = programs.length; p < pl; p ++ ) { 25615 25616 var programInfo = programs[ p ]; 25617 25618 if ( programInfo.code === code ) { 25619 25620 program = programInfo; 25621 ++ program.usedTimes; 25622 25623 break; 25624 25625 } 25626 25627 } 25628 25629 if ( program === undefined ) { 25630 25631 program = new WebGLProgram( renderer, extensions, code, material, shader, parameters ); 25632 programs.push( program ); 25633 25634 } 25635 25636 return program; 25637 25638 }; 25639 25640 this.releaseProgram = function ( program ) { 25641 25642 if ( -- program.usedTimes === 0 ) { 25643 25644 // Remove from unordered set 25645 var i = programs.indexOf( program ); 25646 programs[ i ] = programs[ programs.length - 1 ]; 25647 programs.pop(); 25648 25649 // Free WebGL resources 25650 program.destroy(); 25651 25652 } 25653 25654 }; 25655 25656 // Exposed for resource monitoring & error feedback via renderer.info: 25657 this.programs = programs; 25658 25659 } 25660 25661 /** 25662 * @author fordacious / fordacious.github.io 25663 */ 25664 25665 function WebGLProperties() { 25666 25667 var properties = new WeakMap(); 25668 25669 function get( object ) { 25670 25671 var map = properties.get( object ); 25672 25673 if ( map === undefined ) { 25674 25675 map = {}; 25676 properties.set( object, map ); 25677 25678 } 25679 25680 return map; 25681 25682 } 25683 25684 function remove( object ) { 25685 25686 properties.delete( object ); 25687 25688 } 25689 25690 function update( object, key, value ) { 25691 25692 properties.get( object )[ key ] = value; 25693 25694 } 25695 25696 function dispose() { 25697 25698 properties = new WeakMap(); 25699 25700 } 25701 25702 return { 25703 get: get, 25704 remove: remove, 25705 update: update, 25706 dispose: dispose 25707 }; 25708 25709 } 25710 25711 /** 25712 * @author mrdoob / http://mrdoob.com/ 25713 */ 25714 25715 function painterSortStable( a, b ) { 25716 25717 if ( a.renderOrder !== b.renderOrder ) { 25718 25719 return a.renderOrder - b.renderOrder; 25720 25721 } else if ( a.program && b.program && a.program !== b.program ) { 25722 25723 return a.program.id - b.program.id; 25724 25725 } else if ( a.material.id !== b.material.id ) { 25726 25727 return a.material.id - b.material.id; 25728 25729 } else if ( a.z !== b.z ) { 25730 25731 return a.z - b.z; 25732 25733 } else { 25734 25735 return a.id - b.id; 25736 25737 } 25738 25739 } 25740 25741 function reversePainterSortStable( a, b ) { 25742 25743 if ( a.renderOrder !== b.renderOrder ) { 25744 25745 return a.renderOrder - b.renderOrder; 25746 25747 } if ( a.z !== b.z ) { 25748 25749 return b.z - a.z; 25750 25751 } else { 25752 25753 return a.id - b.id; 25754 25755 } 25756 25757 } 25758 25759 function WebGLRenderList() { 25760 25761 var renderItems = []; 25762 var renderItemsIndex = 0; 25763 25764 var opaque = []; 25765 var transparent = []; 25766 25767 function init() { 25768 25769 renderItemsIndex = 0; 25770 25771 opaque.length = 0; 25772 transparent.length = 0; 25773 25774 } 25775 25776 function push( object, geometry, material, z, group ) { 25777 25778 var renderItem = renderItems[ renderItemsIndex ]; 25779 25780 if ( renderItem === undefined ) { 25781 25782 renderItem = { 25783 id: object.id, 25784 object: object, 25785 geometry: geometry, 25786 material: material, 25787 program: material.program, 25788 renderOrder: object.renderOrder, 25789 z: z, 25790 group: group 25791 }; 25792 25793 renderItems[ renderItemsIndex ] = renderItem; 25794 25795 } else { 25796 25797 renderItem.id = object.id; 25798 renderItem.object = object; 25799 renderItem.geometry = geometry; 25800 renderItem.material = material; 25801 renderItem.program = material.program; 25802 renderItem.renderOrder = object.renderOrder; 25803 renderItem.z = z; 25804 renderItem.group = group; 25805 25806 } 25807 25808 ( material.transparent === true ? transparent : opaque ).push( renderItem ); 25809 25810 renderItemsIndex ++; 25811 25812 } 25813 25814 function sort() { 25815 25816 if ( opaque.length > 1 ) opaque.sort( painterSortStable ); 25817 if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); 25818 25819 } 25820 25821 return { 25822 opaque: opaque, 25823 transparent: transparent, 25824 25825 init: init, 25826 push: push, 25827 25828 sort: sort 25829 }; 25830 25831 } 25832 25833 function WebGLRenderLists() { 25834 25835 var lists = {}; 25836 25837 function get( scene, camera ) { 25838 25839 var hash = scene.id + ',' + camera.id; 25840 var list = lists[ hash ]; 25841 25842 if ( list === undefined ) { 25843 25844 // console.log( 'THREE.WebGLRenderLists:', hash ); 25845 25846 list = new WebGLRenderList(); 25847 lists[ hash ] = list; 25848 25849 } 25850 25851 return list; 25852 25853 } 25854 25855 function dispose() { 25856 25857 lists = {}; 25858 25859 } 25860 25861 return { 25862 get: get,
25863 dispose: dispose 25864 }; 25865 25866 } 25867 25868 /** 25869 * @author mrdoob / http://mrdoob.com/ 25870 */ 25871 25872 function UniformsCache() { 25873 25874 var lights = {}; 25875 25876 return { 25877 25878 get: function ( light ) { 25879 25880 if ( lights[ light.id ] !== undefined ) { 25881 25882 return lights[ light.id ]; 25883 25884 } 25885 25886 var uniforms; 25887 25888 switch ( light.type ) { 25889 25890 case 'DirectionalLight': 25891 uniforms = { 25892 direction: new Vector3(), 25893 color: new Color(), 25894 25895 shadow: false, 25896 shadowBias: 0, 25897 shadowRadius: 1, 25898 shadowMapSize: new Vector2() 25899 }; 25900 break; 25901 25902 case 'SpotLight': 25903 uniforms = { 25904 position: new Vector3(), 25905 direction: new Vector3(), 25906 color: new Color(), 25907 distance: 0, 25908 coneCos: 0, 25909 penumbraCos: 0, 25910 decay: 0, 25911 25912 shadow: false, 25913 shadowBias: 0, 25914 shadowRadius: 1, 25915 shadowMapSize: new Vector2() 25916 }; 25917 break; 25918 25919 case 'PointLight': 25920 uniforms = { 25921 position: new Vector3(), 25922 color: new Color(), 25923 distance: 0, 25924 decay: 0, 25925 25926 shadow: false, 25927 shadowBias: 0, 25928 shadowRadius: 1, 25929 shadowMapSize: new Vector2(), 25930 shadowCameraNear: 1, 25931 shadowCameraFar: 1000 25932 }; 25933 break; 25934 25935 case 'HemisphereLight': 25936 uniforms = { 25937 direction: new Vector3(), 25938 skyColor: new Color(), 25939 groundColor: new Color() 25940 }; 25941 break; 25942 25943 case 'RectAreaLight': 25944 uniforms = { 25945 color: new Color(), 25946 position: new Vector3(), 25947 halfWidth: new Vector3(), 25948 halfHeight: new Vector3() 25949 // TODO (abelnation): set RectAreaLight shadow uniforms 25950 }; 25951 break; 25952 25953 } 25954 25955 lights[ light.id ] = uniforms; 25956 25957 return uniforms; 25958 25959 } 25960 25961 }; 25962 25963 } 25964 25965 var count = 0; 25966 25967 function WebGLLights() { 25968 25969 var cache = new UniformsCache(); 25970 25971 var state = { 25972 25973 id: count ++, 25974 25975 hash: '', 25976 25977 ambient: [ 0, 0, 0 ], 25978 directional: [], 25979 directionalShadowMap: [], 25980 directionalShadowMatrix: [], 25981 spot: [], 25982 spotShadowMap: [], 25983 spotShadowMatrix: [], 25984 rectArea: [], 25985 point: [], 25986 pointShadowMap: [], 25987 pointShadowMatrix: [], 25988 hemi: [] 25989 25990 }; 25991 25992 var vector3 = new Vector3(); 25993 var matrix4 = new Matrix4(); 25994 var matrix42 = new Matrix4(); 25995 25996 function setup( lights, shadows, camera ) { 25997 25998 var r = 0, g = 0, b = 0; 25999 26000 var directionalLength = 0; 26001 var pointLength = 0; 26002 var spotLength = 0; 26003 var rectAreaLength = 0; 26004 var hemiLength = 0; 26005 26006 var viewMatrix = camera.matrixWorldInverse; 26007 26008 for ( var i = 0, l = lights.length; i < l; i ++ ) { 26009 26010 var light = lights[ i ]; 26011 26012 var color = light.color; 26013 var intensity = light.intensity; 26014 var distance = light.distance; 26015 26016 var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; 26017 26018 if ( light.isAmbientLight ) { 26019 26020 r += color.r * intensity; 26021 g += color.g * intensity; 26022 b += color.b * intensity; 26023 26024 } else if ( light.isDirectionalLight ) { 26025 26026 var uniforms = cache.get( light ); 26027 26028 uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); 26029 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 26030 vector3.setFromMatrixPosition( light.target.matrixWorld ); 26031 uniforms.direction.sub( vector3 ); 26032 uniforms.direction.transformDirection( viewMatrix ); 26033 26034 uniforms.shadow = light.castShadow; 26035 26036 if ( light.castShadow ) { 26037 26038 var shadow = light.shadow; 26039 26040 uniforms.shadowBias = shadow.bias; 26041 uniforms.shadowRadius = shadow.radius; 26042 uniforms.shadowMapSize = shadow.mapSize; 26043 26044 } 26045 26046 state.directionalShadowMap[ directionalLength ] = shadowMap; 26047 state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; 26048 state.directional[ directionalLength ] = uniforms; 26049 26050 directionalLength ++; 26051 26052 } else if ( light.isSpotLight ) { 26053 26054 var uniforms = cache.get( light ); 26055 26056 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 26057 uniforms.position.applyMatrix4( viewMatrix ); 26058 26059 uniforms.color.copy( color ).multiplyScalar( intensity ); 26060 uniforms.distance = distance; 26061
26062 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 26063 vector3.setFromMatrixPosition( light.target.matrixWorld ); 26064 uniforms.direction.sub( vector3 ); 26065 uniforms.direction.transformDirection( viewMatrix ); 26066 26067 uniforms.coneCos = Math.cos( light.angle ); 26068 uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); 26069 uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; 26070 26071 uniforms.shadow = light.castShadow; 26072 26073 if ( light.castShadow ) { 26074 26075 var shadow = light.shadow; 26076 26077 uniforms.shadowBias = shadow.bias; 26078 uniforms.shadowRadius = shadow.radius; 26079 uniforms.shadowMapSize = shadow.mapSize; 26080 26081 } 26082 26083 state.spotShadowMap[ spotLength ] = shadowMap; 26084 state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; 26085 state.spot[ spotLength ] = uniforms; 26086 26087 spotLength ++; 26088 26089 } else if ( light.isRectAreaLight ) { 26090 26091 var uniforms = cache.get( light ); 26092 26093 // (a) intensity is the total visible light emitted 26094 //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); 26095 26096 // (b) intensity is the brightness of the light 26097 uniforms.color.copy( color ).multiplyScalar( intensity ); 26098 26099 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 26100 uniforms.position.applyMatrix4( viewMatrix ); 26101 26102 // extract local rotation of light to derive width/height half vectors 26103 matrix42.identity(); 26104 matrix4.copy( light.matrixWorld ); 26105 matrix4.premultiply( viewMatrix ); 26106 matrix42.extractRotation( matrix4 ); 26107 26108 uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); 26109 uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); 26110 26111 uniforms.halfWidth.applyMatrix4( matrix42 ); 26112 uniforms.halfHeight.applyMatrix4( matrix42 ); 26113 26114 // TODO (abelnation): RectAreaLight distance? 26115 // uniforms.distance = distance; 26116 26117 state.rectArea[ rectAreaLength ] = uniforms; 26118 26119 rectAreaLength ++; 26120 26121 } else if ( light.isPointLight ) { 26122 26123 var uniforms = cache.get( light ); 26124 26125 uniforms.position.setFromMatrixPosition( light.matrixWorld ); 26126 uniforms.position.applyMatrix4( viewMatrix ); 26127 26128 uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); 26129 uniforms.distance = light.distance; 26130 uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; 26131 26132 uniforms.shadow = light.castShadow; 26133 26134 if ( light.castShadow ) { 26135 26136 var shadow = light.shadow; 26137 26138 uniforms.shadowBias = shadow.bias; 26139 uniforms.shadowRadius = shadow.radius; 26140 uniforms.shadowMapSize = shadow.mapSize; 26141 uniforms.shadowCameraNear = shadow.camera.near; 26142 uniforms.shadowCameraFar = shadow.camera.far; 26143 26144 } 26145 26146 state.pointShadowMap[ pointLength ] = shadowMap; 26147 state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; 26148 state.point[ pointLength ] = uniforms; 26149 26150 pointLength ++; 26151 26152 } else if ( light.isHemisphereLight ) { 26153 26154 var uniforms = cache.get( light ); 26155 26156 uniforms.direction.setFromMatrixPosition( light.matrixWorld ); 26157 uniforms.direction.transformDirection( viewMatrix ); 26158 uniforms.direction.normalize(); 26159 26160 uniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); 26161 uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); 26162 26163 state.hemi[ hemiLength ] = uniforms; 26164 26165 hemiLength ++; 26166 26167 } 26168 26169 } 26170 26171 state.ambient[ 0 ] = r; 26172 state.ambient[ 1 ] = g; 26173 state.ambient[ 2 ] = b; 26174 26175 state.directional.length = directionalLength; 26176 state.spot.length = spotLength; 26177 state.rectArea.length = rectAreaLength; 26178 state.point.length = pointLength; 26179 state.hemi.length = hemiLength; 26180 26181 state.hash = state.id + ',' + directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + shadows.length; 26182 26183 } 26184 26185 return { 26186 setup: setup, 26187 state: state 26188 }; 26189 26190 } 26191 26192 /** 26193 * @author Mugen87 / https://github.com/Mugen87 26194 */ 26195 26196 function WebGLRenderState() { 26197 26198 var lights = new WebGLLights(); 26199 26200 var lightsArray = []; 26201 var shadowsArray = []; 26202 var spritesArray = []; 26203
vendor: 4,489 bytes, lines 26204-26434
26204 function init() { 26205 26206 lightsArray.length = 0; 26207 shadowsArray.length = 0; 26208 spritesArray.length = 0; 26209 26210 } 26211 26212 function pushLight( light ) { 26213 26214 lightsArray.push( light ); 26215 26216 } 26217 26218 function pushShadow( shadowLight ) { 26219 26220 shadowsArray.push( shadowLight ); 26221 26222 } 26223 26224 function pushSprite( shadowLight ) { 26225 26226 spritesArray.push( shadowLight ); 26227 26228 } 26229 26230 function setupLights( camera ) { 26231 26232 lights.setup( lightsArray, shadowsArray, camera ); 26233 26234 } 26235 26236 var state = { 26237 lightsArray: lightsArray, 26238 shadowsArray: shadowsArray, 26239 spritesArray: spritesArray, 26240 26241 lights: lights 26242 }; 26243 26244 return { 26245 init: init, 26246 state: state, 26247 setupLights: setupLights, 26248 26249 pushLight: pushLight, 26250 pushShadow: pushShadow, 26251 pushSprite: pushSprite 26252 }; 26253 26254 } 26255 26256 function WebGLRenderStates() { 26257 26258 var renderStates = {}; 26259 26260 function get( scene, camera ) { 26261 26262 var hash = scene.id + ',' + camera.id; 26263 26264 var renderState = renderStates[ hash ]; 26265 26266 if ( renderState === undefined ) { 26267 26268 renderState = new WebGLRenderState(); 26269 renderStates[ hash ] = renderState; 26270 26271 } 26272 26273 return renderState; 26274 26275 } 26276 26277 function dispose() { 26278 26279 renderStates = {}; 26280 26281 } 26282 26283 return { 26284 get: get, 26285 dispose: dispose 26286 }; 26287 26288 } 26289 26290 /** 26291 * @author mrdoob / http://mrdoob.com/ 26292 * @author alteredq / http://alteredqualia.com/ 26293 * @author bhouston / https://clara.io 26294 * @author WestLangley / http://github.com/WestLangley 26295 * 26296 * parameters = { 26297 * 26298 * opacity: <float>, 26299 * 26300 * map: new THREE.Texture( <Image> ), 26301 * 26302 * alphaMap: new THREE.Texture( <Image> ), 26303 * 26304 * displacementMap: new THREE.Texture( <Image> ), 26305 * displacementScale: <float>, 26306 * displacementBias: <float>, 26307 * 26308 * wireframe: <boolean>, 26309 * wireframeLinewidth: <float> 26310 * } 26311 */ 26312 26313 function MeshDepthMaterial( parameters ) { 26314 26315 Material.call( this ); 26316 26317 this.type = 'MeshDepthMaterial'; 26318 26319 this.depthPacking = BasicDepthPacking; 26320 26321 this.skinning = false; 26322 this.morphTargets = false; 26323 26324 this.map = null; 26325 26326 this.alphaMap = null; 26327 26328 this.displacementMap = null; 26329 this.displacementScale = 1; 26330 this.displacementBias = 0; 26331 26332 this.wireframe = false; 26333 this.wireframeLinewidth = 1; 26334 26335 this.fog = false; 26336 this.lights = false; 26337 26338 this.setValues( parameters ); 26339 26340 } 26341 26342 MeshDepthMaterial.prototype = Object.create( Material.prototype ); 26343 MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; 26344 26345 MeshDepthMaterial.prototype.isMeshDepthMaterial = true; 26346 26347 MeshDepthMaterial.prototype.copy = function ( source ) { 26348 26349 Material.prototype.copy.call( this, source ); 26350 26351 this.depthPacking = source.depthPacking; 26352 26353 this.skinning = source.skinning; 26354 this.morphTargets = source.morphTargets; 26355 26356 this.map = source.map; 26357 26358 this.alphaMap = source.alphaMap; 26359 26360 this.displacementMap = source.displacementMap; 26361 this.displacementScale = source.displacementScale; 26362 this.displacementBias = source.displacementBias; 26363 26364 this.wireframe = source.wireframe; 26365 this.wireframeLinewidth = source.wireframeLinewidth; 26366 26367 return this; 26368 26369 }; 26370 26371 /** 26372 * @author WestLangley / http://github.com/WestLangley 26373 * 26374 * parameters = { 26375 * 26376 * referencePosition: <float>, 26377 * nearDistance: <float>, 26378 * farDistance: <float>, 26379 * 26380 * skinning: <bool>, 26381 * morphTargets: <bool>, 26382 * 26383 * map: new THREE.Texture( <Image> ), 26384 * 26385 * alphaMap: new THREE.Texture( <Image> ), 26386 * 26387 * displacementMap: new THREE.Texture( <Image> ), 26388 * displacementScale: <float>, 26389 * displacementBias: <float> 26390 * 26391 * } 26392 */ 26393 26394 function MeshDistanceMaterial( parameters ) { 26395 26396 Material.call( this ); 26397 26398 this.type = 'MeshDistanceMaterial'; 26399 26400 this.referencePosition = new Vector3(); 26401 this.nearDistance = 1; 26402 this.farDistance = 1000; 26403 26404 this.skinning = false; 26405 this.morphTargets = false; 26406 26407 this.map = null; 26408 26409 this.alphaMap = null; 26410 26411 this.displacementMap = null; 26412 this.displacementScale = 1; 26413 this.displacementBias = 0; 26414 26415 this.fog = false; 26416 this.lights = false; 26417 26418 this.setValues( parameters ); 26419 26420 } 26421 26422 MeshDistanceMaterial.prototype = Object.create( Material.prototype ); 26423 MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; 26424 26425 MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; 26426 26427 MeshDistanceMaterial.prototype.copy = function ( source ) { 26428 26429 Material.prototype.copy.call( this, source ); 26430 26431 this.referencePosition.copy( source.referencePosition ); 26432 this.nearDistance = source.nearDistance; 26433 this.farDistance = source.farDistance; 26434
26435 this.skinning = source.skinning; 26436 this.morphTargets = source.morphTargets; 26437 26438 this.map = source.map; 26439 26440 this.alphaMap = source.alphaMap; 26441 26442 this.displacementMap = source.displacementMap; 26443 this.displacementScale = source.displacementScale; 26444 this.displacementBias = source.displacementBias; 26445 26446 return this; 26447 26448 }; 26449 26450 /** 26451 * @author alteredq / http://alteredqualia.com/ 26452 * @author mrdoob / http://mrdoob.com/ 26453 */ 26454 26455 function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { 26456 26457 var _frustum = new Frustum(), 26458 _projScreenMatrix = new Matrix4(), 26459 26460 _shadowMapSize = new Vector2(), 26461 _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), 26462 26463 _lookTarget = new Vector3(), 26464 _lightPositionWorld = new Vector3(), 26465 26466 _MorphingFlag = 1, 26467 _SkinningFlag = 2, 26468 26469 _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, 26470 26471 _depthMaterials = new Array( _NumberOfMaterialVariants ), 26472 _distanceMaterials = new Array( _NumberOfMaterialVariants ), 26473 26474 _materialCache = {}; 26475 26476 var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; 26477 26478 var cubeDirections = [ 26479 new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), 26480 new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) 26481 ]; 26482 26483 var cubeUps = [ 26484 new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), 26485 new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) 26486 ]; 26487 26488 var cube2DViewPorts = [ 26489 new Vector4(), new Vector4(), new Vector4(), 26490 new Vector4(), new Vector4(), new Vector4() 26491 ]; 26492 26493 // init 26494 26495 for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) { 26496 26497 var useMorphing = ( i & _MorphingFlag ) !== 0; 26498 var useSkinning = ( i & _SkinningFlag ) !== 0; 26499 26500 var depthMaterial = new MeshDepthMaterial( { 26501 26502 depthPacking: RGBADepthPacking, 26503 26504 morphTargets: useMorphing, 26505 skinning: useSkinning 26506 26507 } ); 26508 26509 _depthMaterials[ i ] = depthMaterial; 26510 26511 // 26512 26513 var distanceMaterial = new MeshDistanceMaterial( { 26514 26515 morphTargets: useMorphing, 26516 skinning: useSkinning 26517 26518 } ); 26519 26520 _distanceMaterials[ i ] = distanceMaterial; 26521 26522 } 26523 26524 // 26525 26526 var scope = this; 26527 26528 this.enabled = false; 26529 26530 this.autoUpdate = true; 26531 this.needsUpdate = false; 26532 26533 this.type = PCFShadowMap; 26534 26535 this.render = function ( lights, scene, camera ) { 26536 26537 if ( scope.enabled === false ) return; 26538 if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; 26539 26540 if ( lights.length === 0 ) return; 26541 26542 // TODO Clean up (needed in case of contextlost) 26543 var _gl = _renderer.context; 26544 var _state = _renderer.state; 26545 26546 // Set GL state for depth map. 26547 _state.disable( _gl.BLEND ); 26548 _state.buffers.color.setClear( 1, 1, 1, 1 ); 26549 _state.buffers.depth.setTest( true ); 26550 _state.setScissorTest( false ); 26551 26552 // render depth map 26553 26554 var faceCount; 26555 26556 for ( var i = 0, il = lights.length; i < il; i ++ ) { 26557 26558 var light = lights[ i ]; 26559 var shadow = light.shadow; 26560 var isPointLight = light && light.isPointLight; 26561 26562 if ( shadow === undefined ) { 26563 26564 console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); 26565 continue; 26566 26567 } 26568 26569 var shadowCamera = shadow.camera; 26570 26571 _shadowMapSize.copy( shadow.mapSize ); 26572 _shadowMapSize.min( _maxShadowMapSize ); 26573 26574 if ( isPointLight ) { 26575 26576 var vpWidth = _shadowMapSize.x; 26577 var vpHeight = _shadowMapSize.y; 26578 26579 // These viewports map a cube-map onto a 2D texture with the 26580 // following orientation: 26581 // 26582 // xzXZ 26583 // y Y 26584 // 26585 // X - Positive x direction 26586 // x - Negative x direction 26587 // Y - Positive y direction 26588 // y - Negative y direction 26589 // Z - Positive z direction 26590 // z - Negative z direction 26591 26592 // positive X 26593 cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); 26594 // negative X 26595 cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); 26596 // positive Z 26597 cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); 26598 // negative Z 26599 cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); 26600 // positive Y 26601 cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); 26602 // negative Y 26603 cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); 26604 26605 _shadowMapSize.x *= 4.0; 26606 _shadowMapSize.y *= 2.0; 26607 26608 } 26609 26610 if ( shadow.map === null ) { 26611 26612 var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; 26613 26614 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); 26615 shadow.map.texture.name = light.name + ".shadowMap"; 26616 26617 shadowCamera.updateProjectionMatrix(); 26618 26619 } 26620 26621 if ( shadow.isSpotLightShadow ) { 26622 26623 shadow.update( light ); 26624 26625 } 26626 26627 var shadowMap = shadow.map; 26628 var shadowMatrix = shadow.matrix; 26629 26630 _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); 26631 shadowCamera.position.copy( _lightPositionWorld ); 26632 26633 if ( isPointLight ) { 26634 26635 faceCount = 6; 26636 26637 // for point lights we set the shadow matrix to be a translation-only matrix 26638 // equal to inverse of the light's position 26639 26640 shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); 26641 26642 } else { 26643
26644 faceCount = 1; 26645 26646 _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); 26647 shadowCamera.lookAt( _lookTarget ); 26648 shadowCamera.updateMatrixWorld(); 26649 26650 // compute shadow matrix 26651 26652 shadowMatrix.set( 26653 0.5, 0.0, 0.0, 0.5, 26654 0.0, 0.5, 0.0, 0.5, 26655 0.0, 0.0, 0.5, 0.5, 26656 0.0, 0.0, 0.0, 1.0 26657 ); 26658 26659 shadowMatrix.multiply( shadowCamera.projectionMatrix ); 26660 shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); 26661 26662 } 26663 26664 _renderer.setRenderTarget( shadowMap ); 26665 _renderer.clear(); 26666 26667 // render shadow map for each cube face (if omni-directional) or 26668 // run a single pass if not 26669 26670 for ( var face = 0; face < faceCount; face ++ ) { 26671 26672 if ( isPointLight ) { 26673 26674 _lookTarget.copy( shadowCamera.position ); 26675 _lookTarget.add( cubeDirections[ face ] ); 26676 shadowCamera.up.copy( cubeUps[ face ] ); 26677 shadowCamera.lookAt( _lookTarget ); 26678 shadowCamera.updateMatrixWorld(); 26679 26680 var vpDimensions = cube2DViewPorts[ face ]; 26681 _state.viewport( vpDimensions ); 26682 26683 } 26684 26685 // update camera matrices and frustum 26686 26687 _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); 26688 _frustum.setFromMatrix( _projScreenMatrix ); 26689 26690 // set object matrices & frustum culling 26691 26692 renderObject( scene, camera, shadowCamera, isPointLight ); 26693 26694 } 26695 26696 } 26697 26698 scope.needsUpdate = false; 26699 26700 }; 26701 26702 function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { 26703 26704 var geometry = object.geometry; 26705 26706 var result = null; 26707 26708 var materialVariants = _depthMaterials; 26709 var customMaterial = object.customDepthMaterial; 26710 26711 if ( isPointLight ) { 26712 26713 materialVariants = _distanceMaterials; 26714 customMaterial = object.customDistanceMaterial; 26715 26716 } 26717 26718 if ( ! customMaterial ) { 26719 26720 var useMorphing = false; 26721 26722 if ( material.morphTargets ) { 26723 26724 if ( geometry && geometry.isBufferGeometry ) { 26725 26726 useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; 26727 26728 } else if ( geometry && geometry.isGeometry ) { 26729 26730 useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; 26731 26732 } 26733 26734 } 26735 26736 if ( object.isSkinnedMesh && material.skinning === false ) { 26737 26738 console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); 26739 26740 } 26741 26742 var useSkinning = object.isSkinnedMesh && material.skinning; 26743 26744 var variantIndex = 0; 26745 26746 if ( useMorphing ) variantIndex |= _MorphingFlag; 26747 if ( useSkinning ) variantIndex |= _SkinningFlag; 26748 26749 result = materialVariants[ variantIndex ]; 26750 26751 } else { 26752 26753 result = customMaterial; 26754 26755 } 26756 26757 if ( _renderer.localClippingEnabled &&
26758 material.clipShadows === true && 26759 material.clippingPlanes.length !== 0 ) { 26760 26761 // in this case we need a unique material instance reflecting the 26762 // appropriate state 26763 26764 var keyA = result.uuid, keyB = material.uuid; 26765 26766 var materialsForVariant = _materialCache[ keyA ]; 26767 26768 if ( materialsForVariant === undefined ) { 26769 26770 materialsForVariant = {}; 26771 _materialCache[ keyA ] = materialsForVariant; 26772 26773 } 26774 26775 var cachedMaterial = materialsForVariant[ keyB ]; 26776 26777 if ( cachedMaterial === undefined ) { 26778 26779 cachedMaterial = result.clone(); 26780 materialsForVariant[ keyB ] = cachedMaterial; 26781 26782 } 26783 26784 result = cachedMaterial; 26785 26786 } 26787 26788 result.visible = material.visible; 26789 result.wireframe = material.wireframe; 26790 26791 result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; 26792 26793 result.clipShadows = material.clipShadows; 26794 result.clippingPlanes = material.clippingPlanes; 26795 result.clipIntersection = material.clipIntersection; 26796 26797 result.wireframeLinewidth = material.wireframeLinewidth; 26798 result.linewidth = material.linewidth; 26799 26800 if ( isPointLight && result.isMeshDistanceMaterial ) { 26801 26802 result.referencePosition.copy( lightPositionWorld ); 26803 result.nearDistance = shadowCameraNear; 26804 result.farDistance = shadowCameraFar; 26805 26806 } 26807 26808 return result; 26809 26810 } 26811 26812 function renderObject( object, camera, shadowCamera, isPointLight ) { 26813 26814 if ( object.visible === false ) return; 26815 26816 var visible = object.layers.test( camera.layers ); 26817 26818 if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { 26819 26820 if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { 26821 26822 object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); 26823 26824 var geometry = _objects.update( object ); 26825 var material = object.material; 26826 26827 if ( Array.isArray( material ) ) { 26828 26829 var groups = geometry.groups; 26830 26831 for ( var k = 0, kl = groups.length; k < kl; k ++ ) { 26832 26833 var group = groups[ k ]; 26834 var groupMaterial = material[ group.materialIndex ]; 26835 26836 if ( groupMaterial && groupMaterial.visible ) { 26837 26838 var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); 26839 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); 26840 26841 } 26842 26843 } 26844 26845 } else if ( material.visible ) { 26846 26847 var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); 26848 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); 26849 26850 } 26851 26852 } 26853 26854 } 26855 26856 var children = object.children; 26857 26858 for ( var i = 0, l = children.length; i < l; i ++ ) { 26859 26860 renderObject( children[ i ], camera, shadowCamera, isPointLight ); 26861 26862 } 26863 26864 } 26865 26866 } 26867 26868 /** 26869 * @author mrdoob / http://mrdoob.com/ 26870 */ 26871 26872 function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { 26873 26874 Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 26875 26876 this.needsUpdate = true; 26877 26878 } 26879 26880 CanvasTexture.prototype = Object.create( Texture.prototype ); 26881 CanvasTexture.prototype.constructor = CanvasTexture; 26882 CanvasTexture.prototype.isCanvasTexture = true; 26883 26884 /** 26885 * @author mikael emtinger / http://gomo.se/ 26886 * @author alteredq / http://alteredqualia.com/ 26887 */ 26888 26889 function WebGLSpriteRenderer( renderer, gl, state, textures, capabilities ) { 26890 26891 var vertexBuffer, elementBuffer; 26892 var program, attributes, uniforms; 26893 26894 var texture; 26895 26896 // decompose matrixWorld 26897 26898 var spritePosition = new Vector3(); 26899 var spriteRotation = new Quaternion(); 26900 var spriteScale = new Vector3(); 26901 26902 function init() { 26903 26904 var vertices = new Float32Array( [ 26905 - 0.5, - 0.5, 0, 0, 26906 0.5, - 0.5, 1, 0, 26907 0.5, 0.5, 1, 1, 26908 - 0.5, 0.5, 0, 1 26909 ] ); 26910 26911 var faces = new Uint16Array( [ 26912 0, 1, 2, 26913 0, 2, 3 26914 ] ); 26915 26916 vertexBuffer = gl.createBuffer(); 26917 elementBuffer = gl.createBuffer(); 26918 26919 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer ); 26920 gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW ); 26921 26922 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); 26923 gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW ); 26924 26925 program = createProgram(); 26926 26927 attributes = { 26928 position: gl.getAttribLocation( program, 'position' ), 26929 uv: gl.getAttribLocation( program, 'uv' ) 26930 }; 26931 26932 uniforms = { 26933 uvOffset: gl.getUniformLocation( program, 'uvOffset' ), 26934 uvScale: gl.getUniformLocation( program, 'uvScale' ), 26935 26936 rotation: gl.getUniformLocation( program, 'rotation' ), 26937 center: gl.getUniformLocation( program, 'center' ), 26938 scale: gl.getUniformLocation( program, 'scale' ), 26939 26940 color: gl.getUniformLocation( program, 'color' ), 26941 map: gl.getUniformLocation( program, 'map' ), 26942 opacity: gl.getUniformLocation( program, 'opacity' ), 26943 26944 modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ), 26945 projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ), 26946 26947 fogType: gl.getUniformLocation( program, 'fogType' ), 26948 fogDensity: gl.getUniformLocation( program, 'fogDensity' ), 26949 fogNear: gl.getUniformLocation( program, 'fogNear' ), 26950 fogFar: gl.getUniformLocation( program, 'fogFar' ), 26951 fogColor: gl.getUniformLocation( program, 'fogColor' ), 26952 fogDepth: gl.getUniformLocation( program, 'fogDepth' ), 26953 26954 alphaTest: gl.getUniformLocation( program, 'alphaTest' ) 26955 }; 26956 26957 var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 26958 canvas.width = 8; 26959 canvas.height = 8; 26960 26961 var context = canvas.getContext( '2d' ); 26962 context.fillStyle = 'white'; 26963 context.fillRect( 0, 0, 8, 8 ); 26964 26965 texture = new CanvasTexture( canvas ); 26966 26967 } 26968 26969 this.render = function ( sprites, scene, camera ) { 26970 26971 if ( sprites.length === 0 ) return; 26972 26973 // setup gl 26974 26975 if ( program === undefined ) { 26976 26977 init(); 26978 26979 } 26980 26981 state.useProgram( program ); 26982 26983 state.initAttributes(); 26984 state.enableAttribute( attributes.position ); 26985 state.enableAttribute( attributes.uv ); 26986 state.disableUnusedAttributes(); 26987 26988 state.disable( gl.CULL_FACE ); 26989 state.enable( gl.BLEND ); 26990 26991 gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer ); 26992 gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 ); 26993 gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 ); 26994 26995 gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer ); 26996 26997 gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); 26998 26999 state.activeTexture( gl.TEXTURE0 ); 27000 gl.uniform1i( uniforms.map, 0 ); 27001 27002 var oldFogType = 0; 27003 var sceneFogType = 0; 27004 var fog = scene.fog; 27005 27006 if ( fog ) { 27007 27008 gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b ); 27009 27010 if ( fog.isFog ) { 27011 27012 gl.uniform1f( uniforms.fogNear, fog.near ); 27013 gl.uniform1f( uniforms.fogFar, fog.far ); 27014 27015 gl.uniform1i( uniforms.fogType, 1 ); 27016 oldFogType = 1; 27017 sceneFogType = 1; 27018 27019 } else if ( fog.isFogExp2 ) { 27020 27021 gl.uniform1f( uniforms.fogDensity, fog.density ); 27022 27023 gl.uniform1i( uniforms.fogType, 2 ); 27024 oldFogType = 2; 27025 sceneFogType = 2; 27026 27027 } 27028 27029 } else { 27030
27031 gl.uniform1i( uniforms.fogType, 0 ); 27032 oldFogType = 0; 27033 sceneFogType = 0; 27034 27035 } 27036 27037 27038 // update positions and sort 27039 27040 for ( var i = 0, l = sprites.length; i < l; i ++ ) { 27041 27042 var sprite = sprites[ i ]; 27043 27044 sprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld ); 27045 sprite.z = - sprite.modelViewMatrix.elements[ 14 ]; 27046 27047 } 27048 27049 sprites.sort( painterSortStable ); 27050 27051 // render all sprites 27052 27053 var scale = []; 27054 var center = []; 27055 27056 for ( var i = 0, l = sprites.length; i < l; i ++ ) { 27057 27058 var sprite = sprites[ i ]; 27059 var material = sprite.material; 27060 27061 if ( material.visible === false ) continue; 27062 27063 sprite.onBeforeRender( renderer, scene, camera, undefined, material, undefined ); 27064 27065 gl.uniform1f( uniforms.alphaTest, material.alphaTest ); 27066 gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements ); 27067 27068 sprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale ); 27069 27070 scale[ 0 ] = spriteScale.x; 27071 scale[ 1 ] = spriteScale.y; 27072 27073 center[ 0 ] = sprite.center.x - 0.5; 27074 center[ 1 ] = sprite.center.y - 0.5; 27075 27076 var fogType = 0; 27077 27078 if ( scene.fog && material.fog ) { 27079 27080 fogType = sceneFogType; 27081 27082 } 27083 27084 if ( oldFogType !== fogType ) { 27085 27086 gl.uniform1i( uniforms.fogType, fogType ); 27087 oldFogType = fogType; 27088 27089 } 27090 27091 if ( material.map !== null ) { 27092 27093 gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y ); 27094 gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y ); 27095 27096 } else { 27097 27098 gl.uniform2f( uniforms.uvOffset, 0, 0 ); 27099 gl.uniform2f( uniforms.uvScale, 1, 1 ); 27100 27101 } 27102 27103 gl.uniform1f( uniforms.opacity, material.opacity ); 27104 gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b ); 27105 27106 gl.uniform1f( uniforms.rotation, material.rotation ); 27107 gl.uniform2fv( uniforms.center, center ); 27108 gl.uniform2fv( uniforms.scale, scale ); 27109 27110 state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); 27111 state.buffers.depth.setTest( material.depthTest ); 27112 state.buffers.depth.setMask( material.depthWrite ); 27113 state.buffers.color.setMask( material.colorWrite ); 27114 27115 textures.setTexture2D( material.map || texture, 0 ); 27116 27117 gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); 27118 27119 sprite.onAfterRender( renderer, scene, camera, undefined, material, undefined ); 27120 27121 } 27122 27123 // restore gl 27124 27125 state.enable( gl.CULL_FACE ); 27126 27127 state.reset(); 27128 27129 }; 27130 27131 function createProgram() { 27132 27133 var program = gl.createProgram(); 27134 27135 var vertexShader = gl.createShader( gl.VERTEX_SHADER ); 27136 var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER ); 27137 27138 gl.shaderSource( vertexShader, [ 27139 27140 'precision ' + capabilities.precision + ' float;', 27141 27142 '#define SHADER_NAME ' + 'SpriteMaterial', 27143 27144 'uniform mat4 modelViewMatrix;', 27145 'uniform mat4 projectionMatrix;', 27146 'uniform float rotation;', 27147 'uniform vec2 center;', 27148 'uniform vec2 scale;', 27149 'uniform vec2 uvOffset;', 27150 'uniform vec2 uvScale;', 27151 27152 'attribute vec2 position;', 27153 'attribute vec2 uv;', 27154 27155 'varying vec2 vUV;', 27156 'varying float fogDepth;', 27157 27158 'void main() {', 27159 27160 ' vUV = uvOffset + uv * uvScale;', 27161 27162 ' vec2 alignedPosition = ( position - center ) * scale;', 27163 27164 ' vec2 rotatedPosition;', 27165 ' rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;', 27166 ' rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;', 27167 27168 ' vec4 mvPosition;', 27169 27170 ' mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );', 27171 ' mvPosition.xy += rotatedPosition;', 27172 27173 ' gl_Position = projectionMatrix * mvPosition;', 27174 27175 ' fogDepth = - mvPosition.z;', 27176 27177 '}' 27178 27179 ].join( '\n' ) ); 27180 27181 gl.shaderSource( fragmentShader, [ 27182 27183 'precision ' + capabilities.precision + ' float;', 27184 27185 '#define SHADER_NAME ' + 'SpriteMaterial', 27186 27187 'uniform vec3 color;', 27188 'uniform sampler2D map;', 27189 'uniform float opacity;', 27190 27191 'uniform int fogType;', 27192 'uniform vec3 fogColor;', 27193 'uniform float fogDensity;', 27194 'uniform float fogNear;', 27195 'uniform float fogFar;', 27196 'uniform float alphaTest;', 27197 27198 'varying vec2 vUV;', 27199 'varying float fogDepth;', 27200 27201 'void main() {', 27202 27203 ' vec4 texture = texture2D( map, vUV );', 27204 27205 ' gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );', 27206 27207 ' if ( gl_FragColor.a < alphaTest ) discard;', 27208 27209 ' if ( fogType > 0 ) {', 27210 27211 ' float fogFactor = 0.0;', 27212 27213 ' if ( fogType == 1 ) {', 27214 27215 ' fogFactor = smoothstep( fogNear, fogFar, fogDepth );', 27216 27217 ' } else {', 27218 27219 ' const float LOG2 = 1.442695;', 27220 ' fogFactor = exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 );', 27221 ' fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );', 27222 27223 ' }', 27224 27225 ' gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );', 27226 27227 ' }', 27228 27229 '}' 27230 27231 ].join( '\n' ) ); 27232 27233 gl.compileShader( vertexShader ); 27234 gl.compileShader( fragmentShader ); 27235 27236 gl.attachShader( program, vertexShader ); 27237 gl.attachShader( program, fragmentShader ); 27238 27239 gl.linkProgram( program ); 27240 27241 return program; 27242
vendor: 5,248 bytes, lines 27243-27553
27243 } 27244 27245 function painterSortStable( a, b ) { 27246 27247 if ( a.renderOrder !== b.renderOrder ) { 27248 27249 return a.renderOrder - b.renderOrder; 27250 27251 } else if ( a.z !== b.z ) { 27252 27253 return b.z - a.z; 27254 27255 } else { 27256 27257 return b.id - a.id; 27258 27259 } 27260 27261 } 27262 27263 } 27264 27265 /** 27266 * @author mrdoob / http://mrdoob.com/ 27267 */ 27268 27269 function WebGLState( gl, extensions, utils ) { 27270 27271 function ColorBuffer() { 27272 27273 var locked = false; 27274 27275 var color = new Vector4(); 27276 var currentColorMask = null; 27277 var currentColorClear = new Vector4( 0, 0, 0, 0 ); 27278 27279 return { 27280 27281 setMask: function ( colorMask ) { 27282 27283 if ( currentColorMask !== colorMask && ! locked ) { 27284 27285 gl.colorMask( colorMask, colorMask, colorMask, colorMask ); 27286 currentColorMask = colorMask; 27287 27288 } 27289 27290 }, 27291 27292 setLocked: function ( lock ) { 27293 27294 locked = lock; 27295 27296 }, 27297 27298 setClear: function ( r, g, b, a, premultipliedAlpha ) { 27299 27300 if ( premultipliedAlpha === true ) { 27301 27302 r *= a; g *= a; b *= a; 27303 27304 } 27305 27306 color.set( r, g, b, a ); 27307 27308 if ( currentColorClear.equals( color ) === false ) { 27309 27310 gl.clearColor( r, g, b, a ); 27311 currentColorClear.copy( color ); 27312 27313 } 27314 27315 }, 27316 27317 reset: function () { 27318 27319 locked = false; 27320 27321 currentColorMask = null; 27322 currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state 27323 27324 } 27325 27326 }; 27327 27328 } 27329 27330 function DepthBuffer() { 27331 27332 var locked = false; 27333 27334 var currentDepthMask = null; 27335 var currentDepthFunc = null; 27336 var currentDepthClear = null; 27337 27338 return { 27339 27340 setTest: function ( depthTest ) { 27341 27342 if ( depthTest ) { 27343 27344 enable( gl.DEPTH_TEST ); 27345 27346 } else { 27347 27348 disable( gl.DEPTH_TEST ); 27349 27350 } 27351 27352 }, 27353 27354 setMask: function ( depthMask ) { 27355 27356 if ( currentDepthMask !== depthMask && ! locked ) { 27357 27358 gl.depthMask( depthMask ); 27359 currentDepthMask = depthMask; 27360 27361 } 27362 27363 }, 27364 27365 setFunc: function ( depthFunc ) { 27366 27367 if ( currentDepthFunc !== depthFunc ) { 27368 27369 if ( depthFunc ) { 27370 27371 switch ( depthFunc ) { 27372 27373 case NeverDepth: 27374 27375 gl.depthFunc( gl.NEVER ); 27376 break; 27377 27378 case AlwaysDepth: 27379 27380 gl.depthFunc( gl.ALWAYS ); 27381 break; 27382 27383 case LessDepth: 27384 27385 gl.depthFunc( gl.LESS ); 27386 break; 27387 27388 case LessEqualDepth: 27389 27390 gl.depthFunc( gl.LEQUAL ); 27391 break; 27392 27393 case EqualDepth: 27394 27395 gl.depthFunc( gl.EQUAL ); 27396 break; 27397 27398 case GreaterEqualDepth: 27399 27400 gl.depthFunc( gl.GEQUAL ); 27401 break; 27402 27403 case GreaterDepth: 27404 27405 gl.depthFunc( gl.GREATER ); 27406 break; 27407 27408 case NotEqualDepth: 27409 27410 gl.depthFunc( gl.NOTEQUAL ); 27411 break; 27412 27413 default: 27414 27415 gl.depthFunc( gl.LEQUAL ); 27416 27417 } 27418 27419 } else { 27420 27421 gl.depthFunc( gl.LEQUAL ); 27422 27423 } 27424 27425 currentDepthFunc = depthFunc; 27426 27427 } 27428 27429 }, 27430 27431 setLocked: function ( lock ) { 27432 27433 locked = lock; 27434 27435 }, 27436 27437 setClear: function ( depth ) { 27438 27439 if ( currentDepthClear !== depth ) { 27440 27441 gl.clearDepth( depth ); 27442 currentDepthClear = depth; 27443 27444 } 27445 27446 }, 27447 27448 reset: function () { 27449 27450 locked = false; 27451 27452 currentDepthMask = null; 27453 currentDepthFunc = null; 27454 currentDepthClear = null; 27455 27456 } 27457 27458 }; 27459 27460 } 27461 27462 function StencilBuffer() { 27463 27464 var locked = false; 27465 27466 var currentStencilMask = null; 27467 var currentStencilFunc = null; 27468 var currentStencilRef = null; 27469 var currentStencilFuncMask = null; 27470 var currentStencilFail = null; 27471 var currentStencilZFail = null; 27472 var currentStencilZPass = null; 27473 var currentStencilClear = null; 27474 27475 return { 27476 27477 setTest: function ( stencilTest ) { 27478 27479 if ( stencilTest ) { 27480 27481 enable( gl.STENCIL_TEST ); 27482 27483 } else { 27484 27485 disable( gl.STENCIL_TEST ); 27486 27487 } 27488 27489 }, 27490 27491 setMask: function ( stencilMask ) { 27492 27493 if ( currentStencilMask !== stencilMask && ! locked ) { 27494 27495 gl.stencilMask( stencilMask ); 27496 currentStencilMask = stencilMask; 27497 27498 } 27499 27500 }, 27501 27502 setFunc: function ( stencilFunc, stencilRef, stencilMask ) { 27503 27504 if ( currentStencilFunc !== stencilFunc || 27505 currentStencilRef !== stencilRef || 27506 currentStencilFuncMask !== stencilMask ) { 27507 27508 gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); 27509 27510 currentStencilFunc = stencilFunc; 27511 currentStencilRef = stencilRef; 27512 currentStencilFuncMask = stencilMask; 27513 27514 } 27515 27516 }, 27517 27518 setOp: function ( stencilFail, stencilZFail, stencilZPass ) { 27519 27520 if ( currentStencilFail !== stencilFail || 27521 currentStencilZFail !== stencilZFail || 27522 currentStencilZPass !== stencilZPass ) { 27523 27524 gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); 27525 27526 currentStencilFail = stencilFail; 27527 currentStencilZFail = stencilZFail; 27528 currentStencilZPass = stencilZPass; 27529 27530 } 27531 27532 }, 27533 27534 setLocked: function ( lock ) { 27535 27536 locked = lock; 27537 27538 }, 27539 27540 setClear: function ( stencil ) { 27541 27542 if ( currentStencilClear !== stencil ) { 27543 27544 gl.clearStencil( stencil ); 27545 currentStencilClear = stencil; 27546 27547 } 27548 27549 }, 27550 27551 reset: function () { 27552 27553 locked = false;
27554 27555 currentStencilMask = null; 27556 currentStencilFunc = null; 27557 currentStencilRef = null; 27558 currentStencilFuncMask = null; 27559 currentStencilFail = null; 27560 currentStencilZFail = null; 27561 currentStencilZPass = null; 27562 currentStencilClear = null; 27563 27564 } 27565 27566 }; 27567 27568 } 27569 27570 // 27571 27572 var colorBuffer = new ColorBuffer(); 27573 var depthBuffer = new DepthBuffer(); 27574 var stencilBuffer = new StencilBuffer(); 27575 27576 var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); 27577 var newAttributes = new Uint8Array( maxVertexAttributes ); 27578 var enabledAttributes = new Uint8Array( maxVertexAttributes ); 27579 var attributeDivisors = new Uint8Array( maxVertexAttributes ); 27580 27581 var capabilities = {}; 27582 27583 var compressedTextureFormats = null; 27584 27585 var currentProgram = null; 27586 27587 var currentBlending = null; 27588 var currentBlendEquation = null; 27589 var currentBlendSrc = null; 27590 var currentBlendDst = null; 27591 var currentBlendEquationAlpha = null; 27592 var currentBlendSrcAlpha = null; 27593 var currentBlendDstAlpha = null; 27594 var currentPremultipledAlpha = false; 27595 27596 var currentFlipSided = null; 27597 var currentCullFace = null; 27598 27599 var currentLineWidth = null; 27600 27601 var currentPolygonOffsetFactor = null; 27602 var currentPolygonOffsetUnits = null; 27603 27604 var maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); 27605 27606 var lineWidthAvailable = false; 27607 var version = 0; 27608 var glVersion = gl.getParameter( gl.VERSION ); 27609 27610 if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { 27611 27612 version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); 27613 lineWidthAvailable = ( version >= 1.0 ); 27614 27615 } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { 27616 27617 version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); 27618 lineWidthAvailable = ( version >= 2.0 ); 27619 27620 } 27621 27622 var currentTextureSlot = null; 27623 var currentBoundTextures = {}; 27624 27625 var currentScissor = new Vector4(); 27626 var currentViewport = new Vector4(); 27627 27628 function createTexture( type, target, count ) { 27629 27630 var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. 27631 var texture = gl.createTexture(); 27632 27633 gl.bindTexture( type, texture ); 27634 gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); 27635 gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); 27636 27637 for ( var i = 0; i < count; i ++ ) { 27638 27639 gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data ); 27640 27641 } 27642 27643 return texture; 27644 27645 } 27646 27647 var emptyTextures = {}; 27648 emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 ); 27649 emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 ); 27650 27651 // init 27652 27653 colorBuffer.setClear( 0, 0, 0, 1 ); 27654 depthBuffer.setClear( 1 ); 27655 stencilBuffer.setClear( 0 ); 27656 27657 enable( gl.DEPTH_TEST ); 27658 depthBuffer.setFunc( LessEqualDepth ); 27659 27660 setFlipSided( false ); 27661 setCullFace( CullFaceBack ); 27662 enable( gl.CULL_FACE ); 27663 27664 enable( gl.BLEND ); 27665 setBlending( NormalBlending ); 27666 27667 // 27668 27669 function initAttributes() { 27670 27671 for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { 27672 27673 newAttributes[ i ] = 0; 27674 27675 } 27676 27677 } 27678 27679 function enableAttribute( attribute ) { 27680 27681 enableAttributeAndDivisor( attribute, 0 ); 27682 27683 } 27684 27685 function enableAttributeAndDivisor( attribute, meshPerAttribute ) { 27686 27687 newAttributes[ attribute ] = 1; 27688 27689 if ( enabledAttributes[ attribute ] === 0 ) { 27690 27691 gl.enableVertexAttribArray( attribute ); 27692 enabledAttributes[ attribute ] = 1; 27693 27694 } 27695 27696 if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { 27697 27698 var extension = extensions.get( 'ANGLE_instanced_arrays' ); 27699 27700 extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute ); 27701 attributeDivisors[ attribute ] = meshPerAttribute; 27702 27703 } 27704 27705 } 27706 27707 function disableUnusedAttributes() { 27708 27709 for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { 27710 27711 if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { 27712 27713 gl.disableVertexAttribArray( i ); 27714 enabledAttributes[ i ] = 0; 27715 27716 } 27717 27718 } 27719 27720 } 27721 27722 function enable( id ) { 27723 27724 if ( capabilities[ id ] !== true ) { 27725 27726 gl.enable( id ); 27727 capabilities[ id ] = true; 27728 27729 } 27730 27731 } 27732 27733 function disable( id ) { 27734 27735 if ( capabilities[ id ] !== false ) { 27736 27737 gl.disable( id ); 27738 capabilities[ id ] = false;
27739 27740 } 27741 27742 } 27743 27744 function getCompressedTextureFormats() { 27745 27746 if ( compressedTextureFormats === null ) { 27747 27748 compressedTextureFormats = []; 27749 27750 if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || 27751 extensions.get( 'WEBGL_compressed_texture_s3tc' ) || 27752 extensions.get( 'WEBGL_compressed_texture_etc1' ) || 27753 extensions.get( 'WEBGL_compressed_texture_astc' ) ) { 27754 27755 var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS ); 27756 27757 for ( var i = 0; i < formats.length; i ++ ) { 27758 27759 compressedTextureFormats.push( formats[ i ] ); 27760 27761 } 27762 27763 } 27764 27765 } 27766 27767 return compressedTextureFormats; 27768 27769 } 27770 27771 function useProgram( program ) { 27772 27773 if ( currentProgram !== program ) { 27774 27775 gl.useProgram( program ); 27776 27777 currentProgram = program; 27778 27779 return true; 27780 27781 } 27782 27783 return false; 27784 27785 } 27786 27787 function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { 27788 27789 if ( blending !== NoBlending ) { 27790 27791 enable( gl.BLEND ); 27792 27793 } else { 27794 27795 disable( gl.BLEND ); 27796 27797 } 27798 27799 if ( blending !== CustomBlending ) { 27800 27801 if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { 27802 27803 switch ( blending ) { 27804 27805 case AdditiveBlending: 27806 27807 if ( premultipliedAlpha ) { 27808 27809 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); 27810 gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE ); 27811 27812 } else { 27813 27814 gl.blendEquation( gl.FUNC_ADD ); 27815 gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); 27816 27817 } 27818 break; 27819 27820 case SubtractiveBlending: 27821 27822 if ( premultipliedAlpha ) { 27823 27824 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); 27825 gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA ); 27826 27827 } else { 27828 27829 gl.blendEquation( gl.FUNC_ADD ); 27830 gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); 27831 27832 } 27833 break; 27834 27835 case MultiplyBlending: 27836 27837 if ( premultipliedAlpha ) { 27838 27839 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); 27840 gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA ); 27841 27842 } else { 27843 27844 gl.blendEquation( gl.FUNC_ADD ); 27845 gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); 27846 27847 } 27848 break; 27849 27850 default: 27851 27852 if ( premultipliedAlpha ) { 27853 27854 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); 27855 gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); 27856 27857 } else { 27858 27859 gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); 27860 gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); 27861 27862 } 27863 27864 } 27865 27866 } 27867 27868 currentBlendEquation = null; 27869 currentBlendSrc = null; 27870 currentBlendDst = null; 27871 currentBlendEquationAlpha = null; 27872 currentBlendSrcAlpha = null; 27873 currentBlendDstAlpha = null; 27874 27875 } else { 27876 27877 blendEquationAlpha = blendEquationAlpha || blendEquation; 27878 blendSrcAlpha = blendSrcAlpha || blendSrc; 27879 blendDstAlpha = blendDstAlpha || blendDst; 27880 27881 if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { 27882 27883 gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); 27884 27885 currentBlendEquation = blendEquation; 27886 currentBlendEquationAlpha = blendEquationAlpha; 27887 27888 } 27889 27890 if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { 27891 27892 gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); 27893 27894 currentBlendSrc = blendSrc; 27895 currentBlendDst = blendDst; 27896 currentBlendSrcAlpha = blendSrcAlpha; 27897 currentBlendDstAlpha = blendDstAlpha; 27898 27899 } 27900 27901 } 27902 27903 currentBlending = blending; 27904 currentPremultipledAlpha = premultipliedAlpha; 27905 27906 } 27907 27908 function setMaterial( material, frontFaceCW ) { 27909 27910 material.side === DoubleSide 27911 ? disable( gl.CULL_FACE ) 27912 : enable( gl.CULL_FACE ); 27913 27914 var flipSided = ( material.side === BackSide ); 27915 if ( frontFaceCW ) flipSided = ! flipSided; 27916 27917 setFlipSided( flipSided ); 27918 27919 material.transparent === true 27920 ? setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ) 27921 : setBlending( NoBlending ); 27922 27923 depthBuffer.setFunc( material.depthFunc ); 27924 depthBuffer.setTest( material.depthTest ); 27925 depthBuffer.setMask( material.depthWrite ); 27926 colorBuffer.setMask( material.colorWrite ); 27927 27928 setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); 27929 27930 } 27931 27932 // 27933 27934 function setFlipSided( flipSided ) { 27935 27936 if ( currentFlipSided !== flipSided ) { 27937 27938 if ( flipSided ) { 27939 27940 gl.frontFace( gl.CW ); 27941 27942 } else { 27943
27944 gl.frontFace( gl.CCW ); 27945 27946 } 27947 27948 currentFlipSided = flipSided; 27949 27950 } 27951 27952 } 27953 27954 function setCullFace( cullFace ) { 27955 27956 if ( cullFace !== CullFaceNone ) { 27957 27958 enable( gl.CULL_FACE ); 27959 27960 if ( cullFace !== currentCullFace ) { 27961 27962 if ( cullFace === CullFaceBack ) { 27963 27964 gl.cullFace( gl.BACK ); 27965 27966 } else if ( cullFace === CullFaceFront ) { 27967 27968 gl.cullFace( gl.FRONT ); 27969 27970 } else { 27971 27972 gl.cullFace( gl.FRONT_AND_BACK ); 27973 27974 } 27975 27976 } 27977 27978 } else { 27979 27980 disable( gl.CULL_FACE ); 27981 27982 } 27983 27984 currentCullFace = cullFace; 27985 27986 } 27987 27988 function setLineWidth( width ) { 27989 27990 if ( width !== currentLineWidth ) { 27991 27992 if ( lineWidthAvailable ) gl.lineWidth( width ); 27993 27994 currentLineWidth = width; 27995 27996 } 27997 27998 } 27999 28000 function setPolygonOffset( polygonOffset, factor, units ) { 28001 28002 if ( polygonOffset ) { 28003 28004 enable( gl.POLYGON_OFFSET_FILL ); 28005 28006 if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { 28007 28008 gl.polygonOffset( factor, units ); 28009 28010 currentPolygonOffsetFactor = factor; 28011 currentPolygonOffsetUnits = units; 28012 28013 } 28014 28015 } else { 28016 28017 disable( gl.POLYGON_OFFSET_FILL ); 28018 28019 } 28020 28021 } 28022 28023 function setScissorTest( scissorTest ) { 28024 28025 if ( scissorTest ) { 28026 28027 enable( gl.SCISSOR_TEST ); 28028 28029 } else { 28030 28031 disable( gl.SCISSOR_TEST ); 28032 28033 } 28034 28035 } 28036 28037 // texture 28038 28039 function activeTexture( webglSlot ) { 28040 28041 if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; 28042 28043 if ( currentTextureSlot !== webglSlot ) { 28044 28045 gl.activeTexture( webglSlot ); 28046 currentTextureSlot = webglSlot; 28047 28048 } 28049 28050 } 28051 28052 function bindTexture( webglType, webglTexture ) { 28053 28054 if ( currentTextureSlot === null ) { 28055 28056 activeTexture(); 28057 28058 } 28059 28060 var boundTexture = currentBoundTextures[ currentTextureSlot ]; 28061 28062 if ( boundTexture === undefined ) { 28063 28064 boundTexture = { type: undefined, texture: undefined }; 28065 currentBoundTextures[ currentTextureSlot ] = boundTexture; 28066 28067 } 28068 28069 if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { 28070 28071 gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); 28072 28073 boundTexture.type = webglType; 28074 boundTexture.texture = webglTexture; 28075 28076 } 28077 28078 } 28079 28080 function compressedTexImage2D() { 28081 28082 try { 28083 28084 gl.compressedTexImage2D.apply( gl, arguments ); 28085 28086 } catch ( error ) { 28087 28088 console.error( 'THREE.WebGLState:', error ); 28089 28090 } 28091 28092 } 28093 28094 function texImage2D() { 28095 28096 try { 28097 28098 gl.texImage2D.apply( gl, arguments ); 28099 28100 } catch ( error ) { 28101 28102 console.error( 'THREE.WebGLState:', error ); 28103 28104 } 28105 28106 } 28107 28108 // 28109 28110 function scissor( scissor ) { 28111 28112 if ( currentScissor.equals( scissor ) === false ) { 28113 28114 gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); 28115 currentScissor.copy( scissor ); 28116 28117 } 28118 28119 } 28120 28121 function viewport( viewport ) { 28122 28123 if ( currentViewport.equals( viewport ) === false ) { 28124 28125 gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); 28126 currentViewport.copy( viewport ); 28127 28128 } 28129 28130 } 28131 28132 // 28133 28134 function reset() { 28135 28136 for ( var i = 0; i < enabledAttributes.length; i ++ ) { 28137 28138 if ( enabledAttributes[ i ] === 1 ) { 28139 28140 gl.disableVertexAttribArray( i ); 28141 enabledAttributes[ i ] = 0; 28142 28143 } 28144 28145 } 28146 28147 capabilities = {}; 28148 28149 compressedTextureFormats = null; 28150 28151 currentTextureSlot = null; 28152 currentBoundTextures = {}; 28153 28154 currentProgram = null; 28155 28156 currentBlending = null; 28157 28158 currentFlipSided = null; 28159 currentCullFace = null; 28160 28161 colorBuffer.reset(); 28162 depthBuffer.reset(); 28163 stencilBuffer.reset(); 28164 28165 } 28166 28167 return { 28168 28169 buffers: { 28170 color: colorBuffer, 28171 depth: depthBuffer, 28172 stencil: stencilBuffer 28173 }, 28174 28175 initAttributes: initAttributes, 28176 enableAttribute: enableAttribute, 28177 enableAttributeAndDivisor: enableAttributeAndDivisor, 28178 disableUnusedAttributes: disableUnusedAttributes, 28179 enable: enable, 28180 disable: disable, 28181 getCompressedTextureFormats: getCompressedTextureFormats, 28182 28183 useProgram: useProgram, 28184 28185 setBlending: setBlending, 28186 setMaterial: setMaterial, 28187
28188 setFlipSided: setFlipSided, 28189 setCullFace: setCullFace, 28190 28191 setLineWidth: setLineWidth, 28192 setPolygonOffset: setPolygonOffset, 28193 28194 setScissorTest: setScissorTest, 28195 28196 activeTexture: activeTexture, 28197 bindTexture: bindTexture, 28198 compressedTexImage2D: compressedTexImage2D, 28199 texImage2D: texImage2D, 28200 28201 scissor: scissor, 28202 viewport: viewport, 28203 28204 reset: reset 28205 28206 }; 28207 28208 } 28209 28210 /** 28211 * @author mrdoob / http://mrdoob.com/ 28212 */ 28213 28214 function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { 28215 28216 var _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext ); /* global WebGL2RenderingContext */ 28217 var _videoTextures = {}; 28218 var _canvas; 28219 28220 // 28221 28222 function clampToMaxSize( image, maxSize ) { 28223 28224 if ( image.width > maxSize || image.height > maxSize ) { 28225 28226 if ( 'data' in image ) { 28227 28228 console.warn( 'THREE.WebGLRenderer: image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); 28229 return; 28230 28231 } 28232 28233 // Warning: Scaling through the canvas will only work with images that use 28234 // premultiplied alpha. 28235 28236 var scale = maxSize / Math.max( image.width, image.height ); 28237 28238 var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 28239 canvas.width = Math.floor( image.width * scale ); 28240 canvas.height = Math.floor( image.height * scale ); 28241 28242 var context = canvas.getContext( '2d' ); 28243 context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); 28244 28245 console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image ); 28246 28247 return canvas; 28248 28249 } 28250 28251 return image; 28252 28253 } 28254 28255 function isPowerOfTwo( image ) { 28256 28257 return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height ); 28258 28259 } 28260 28261 function makePowerOfTwo( image ) { 28262 28263 if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof ImageBitmap ) { 28264 28265 if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); 28266 28267 _canvas.width = _Math.floorPowerOfTwo( image.width ); 28268 _canvas.height = _Math.floorPowerOfTwo( image.height ); 28269 28270 var context = _canvas.getContext( '2d' ); 28271 context.drawImage( image, 0, 0, _canvas.width, _canvas.height ); 28272 28273 console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + _canvas.width + 'x' + _canvas.height, image ); 28274 28275 return _canvas; 28276 28277 } 28278 28279 return image; 28280 28281 } 28282 28283 function textureNeedsPowerOfTwo( texture ) { 28284 28285 return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || 28286 ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); 28287 28288 } 28289 28290 function textureNeedsGenerateMipmaps( texture, isPowerOfTwo ) { 28291 28292 return texture.generateMipmaps && isPowerOfTwo && 28293 texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; 28294 28295 } 28296 28297 function generateMipmap( target, texture, width, height ) { 28298 28299 _gl.generateMipmap( target ); 28300 28301 var textureProperties = properties.get( texture ); 28302 28303 // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 28304 textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E; 28305 28306 } 28307 28308 // Fallback filters for non-power-of-2 textures 28309 28310 function filterFallback( f ) { 28311 28312 if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) { 28313 28314 return _gl.NEAREST; 28315 28316 } 28317 28318 return _gl.LINEAR; 28319 28320 } 28321 28322 // 28323 28324 function onTextureDispose( event ) { 28325 28326 var texture = event.target; 28327 28328 texture.removeEventListener( 'dispose', onTextureDispose ); 28329 28330 deallocateTexture( texture ); 28331 28332 if ( texture.isVideoTexture ) { 28333 28334 delete _videoTextures[ texture.id ]; 28335 28336 } 28337 28338 info.memory.textures --; 28339 28340 } 28341 28342 function onRenderTargetDispose( event ) { 28343 28344 var renderTarget = event.target; 28345 28346 renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); 28347 28348 deallocateRenderTarget( renderTarget ); 28349 28350 info.memory.textures --; 28351 28352 } 28353 28354 // 28355 28356 function deallocateTexture( texture ) { 28357 28358 var textureProperties = properties.get( texture ); 28359 28360 if ( texture.image && textureProperties.__image__webglTextureCube ) { 28361 28362 // cube texture 28363 28364 _gl.deleteTexture( textureProperties.__image__webglTextureCube ); 28365 28366 } else { 28367
vendor: 4,521 bytes, lines 28368-28535
28368 // 2D texture 28369 28370 if ( textureProperties.__webglInit === undefined ) return; 28371 28372 _gl.deleteTexture( textureProperties.__webglTexture ); 28373 28374 } 28375 28376 // remove all webgl properties 28377 properties.remove( texture ); 28378 28379 } 28380 28381 function deallocateRenderTarget( renderTarget ) { 28382 28383 var renderTargetProperties = properties.get( renderTarget ); 28384 var textureProperties = properties.get( renderTarget.texture ); 28385 28386 if ( ! renderTarget ) return; 28387 28388 if ( textureProperties.__webglTexture !== undefined ) { 28389 28390 _gl.deleteTexture( textureProperties.__webglTexture ); 28391 28392 } 28393 28394 if ( renderTarget.depthTexture ) { 28395 28396 renderTarget.depthTexture.dispose(); 28397 28398 } 28399 28400 if ( renderTarget.isWebGLRenderTargetCube ) { 28401 28402 for ( var i = 0; i < 6; i ++ ) { 28403 28404 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); 28405 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); 28406 28407 } 28408 28409 } else { 28410 28411 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); 28412 if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); 28413 28414 } 28415 28416 properties.remove( renderTarget.texture ); 28417 properties.remove( renderTarget ); 28418 28419 } 28420 28421 // 28422 28423 28424 28425 function setTexture2D( texture, slot ) { 28426 28427 var textureProperties = properties.get( texture ); 28428 28429 if ( texture.isVideoTexture ) updateVideoTexture( texture ); 28430 28431 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 28432 28433 var image = texture.image; 28434 28435 if ( image === undefined ) { 28436 28437 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture ); 28438 28439 } else if ( image.complete === false ) { 28440 28441 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture ); 28442 28443 } else { 28444 28445 uploadTexture( textureProperties, texture, slot ); 28446 return; 28447 28448 } 28449 28450 } 28451 28452 state.activeTexture( _gl.TEXTURE0 + slot ); 28453 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); 28454 28455 } 28456 28457 function setTextureCube( texture, slot ) { 28458 28459 var textureProperties = properties.get( texture ); 28460 28461 if ( texture.image.length === 6 ) { 28462 28463 if ( texture.version > 0 && textureProperties.__version !== texture.version ) { 28464 28465 if ( ! textureProperties.__image__webglTextureCube ) { 28466 28467 texture.addEventListener( 'dispose', onTextureDispose ); 28468 28469 textureProperties.__image__webglTextureCube = _gl.createTexture(); 28470 28471 info.memory.textures ++; 28472 28473 } 28474 28475 state.activeTexture( _gl.TEXTURE0 + slot ); 28476 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); 28477 28478 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); 28479 28480 var isCompressed = ( texture && texture.isCompressedTexture ); 28481 var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); 28482 28483 var cubeImage = []; 28484 28485 for ( var i = 0; i < 6; i ++ ) { 28486 28487 if ( ! isCompressed && ! isDataTexture ) { 28488 28489 cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize ); 28490 28491 } else { 28492 28493 cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; 28494 28495 } 28496 28497 } 28498 28499 var image = cubeImage[ 0 ], 28500 isPowerOfTwoImage = isPowerOfTwo( image ), 28501 glFormat = utils.convert( texture.format ), 28502 glType = utils.convert( texture.type ); 28503 28504 setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage ); 28505 28506 for ( var i = 0; i < 6; i ++ ) { 28507 28508 if ( ! isCompressed ) { 28509 28510 if ( isDataTexture ) { 28511 28512 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); 28513 28514 } else { 28515 28516 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] ); 28517 28518 } 28519 28520 } else { 28521 28522 var mipmap, mipmaps = cubeImage[ i ].mipmaps; 28523 28524 for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { 28525 28526 mipmap = mipmaps[ j ]; 28527 28528 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { 28529 28530 if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { 28531 28532 state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data ); 28533 28534 } else { 28535
28536 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); 28537 28538 } 28539 28540 } else { 28541 28542 state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 28543 28544 } 28545 28546 } 28547 28548 } 28549 28550 } 28551 28552 if ( ! isCompressed ) { 28553 28554 textureProperties.__maxMipLevel = 0; 28555 28556 } else { 28557 28558 textureProperties.__maxMipLevel = mipmaps.length - 1; 28559 28560 } 28561 28562 if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { 28563 28564 // We assume images for cube map have the same size. 28565 generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height ); 28566 28567 } 28568 28569 textureProperties.__version = texture.version; 28570 28571 if ( texture.onUpdate ) texture.onUpdate( texture ); 28572 28573 } else { 28574 28575 state.activeTexture( _gl.TEXTURE0 + slot ); 28576 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); 28577 28578 } 28579 28580 } 28581 28582 } 28583 28584 function setTextureCubeDynamic( texture, slot ) { 28585 28586 state.activeTexture( _gl.TEXTURE0 + slot ); 28587 state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture ); 28588 28589 } 28590 28591 function setTextureParameters( textureType, texture, isPowerOfTwoImage ) { 28592 28593 var extension; 28594 28595 if ( isPowerOfTwoImage ) { 28596 28597 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) ); 28598 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) ); 28599 28600 _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, utils.convert( texture.magFilter ) ); 28601 _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, utils.convert( texture.minFilter ) ); 28602 28603 } else { 28604 28605 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); 28606 _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); 28607 28608 if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) { 28609 28610 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture ); 28611 28612 } 28613 28614 _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); 28615 _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); 28616 28617 if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) { 28618 28619 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture ); 28620 28621 } 28622 28623 } 28624 28625 extension = extensions.get( 'EXT_texture_filter_anisotropic' ); 28626 28627 if ( extension ) { 28628 28629 if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; 28630 if ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return; 28631 28632 if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { 28633 28634 _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) ); 28635 properties.get( texture ).__currentAnisotropy = texture.anisotropy; 28636 28637 } 28638 28639 } 28640 28641 } 28642 28643 function uploadTexture( textureProperties, texture, slot ) { 28644 28645 if ( textureProperties.__webglInit === undefined ) { 28646 28647 textureProperties.__webglInit = true; 28648 28649 texture.addEventListener( 'dispose', onTextureDispose ); 28650 28651 textureProperties.__webglTexture = _gl.createTexture(); 28652 28653 info.memory.textures ++; 28654 28655 } 28656 28657 state.activeTexture( _gl.TEXTURE0 + slot ); 28658 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); 28659 28660 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); 28661 _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); 28662 _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); 28663 28664 var image = clampToMaxSize( texture.image, capabilities.maxTextureSize ); 28665 28666 if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) { 28667 28668 image = makePowerOfTwo( image ); 28669 28670 } 28671 28672 var isPowerOfTwoImage = isPowerOfTwo( image ), 28673 glFormat = utils.convert( texture.format ), 28674 glType = utils.convert( texture.type ); 28675 28676 setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage ); 28677 28678 var mipmap, mipmaps = texture.mipmaps; 28679 28680 if ( texture.isDepthTexture ) { 28681 28682 // populate depth texture with dummy data 28683 28684 var internalFormat = _gl.DEPTH_COMPONENT; 28685 28686 if ( texture.type === FloatType ) { 28687
28688 if ( ! _isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); 28689 internalFormat = _gl.DEPTH_COMPONENT32F; 28690 28691 } else if ( _isWebGL2 ) { 28692 28693 // WebGL 2.0 requires signed internalformat for glTexImage2D 28694 internalFormat = _gl.DEPTH_COMPONENT16; 28695 28696 } 28697 28698 if ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) { 28699 28700 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 28701 // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT 28702 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 28703 if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { 28704 28705 console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); 28706 28707 texture.type = UnsignedShortType; 28708 glType = utils.convert( texture.type ); 28709 28710 } 28711 28712 } 28713 28714 // Depth stencil textures need the DEPTH_STENCIL internal format 28715 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 28716 if ( texture.format === DepthStencilFormat ) { 28717 28718 internalFormat = _gl.DEPTH_STENCIL; 28719 28720 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are 28721 // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. 28722 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) 28723 if ( texture.type !== UnsignedInt248Type ) { 28724 28725 console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' ); 28726 28727 texture.type = UnsignedInt248Type; 28728 glType = utils.convert( texture.type ); 28729 28730 } 28731 28732 } 28733 28734 state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null ); 28735 28736 } else if ( texture.isDataTexture ) { 28737 28738 // use manually created mipmaps if available 28739 // if there are no manual mipmaps 28740 // set 0 level mipmap and then use GL to generate other mipmap levels 28741 28742 if ( mipmaps.length > 0 && isPowerOfTwoImage ) { 28743 28744 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 28745 28746 mipmap = mipmaps[ i ]; 28747 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 28748 28749 } 28750 28751 texture.generateMipmaps = false; 28752 textureProperties.__maxMipLevel = mipmaps.length - 1; 28753 28754 } else { 28755 28756 state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data ); 28757 textureProperties.__maxMipLevel = 0; 28758 28759 } 28760 28761 } else if ( texture.isCompressedTexture ) { 28762 28763 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 28764 28765 mipmap = mipmaps[ i ]; 28766 28767 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { 28768 28769 if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { 28770 28771 state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data ); 28772 28773 } else { 28774 28775 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); 28776 28777 } 28778 28779 } else { 28780 28781 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); 28782 28783 } 28784 28785 } 28786 28787 textureProperties.__maxMipLevel = mipmaps.length - 1; 28788 28789 } else { 28790 28791 // regular Texture (image, video, canvas) 28792 28793 // use manually created mipmaps if available 28794 // if there are no manual mipmaps 28795 // set 0 level mipmap and then use GL to generate other mipmap levels 28796 28797 if ( mipmaps.length > 0 && isPowerOfTwoImage ) { 28798 28799 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { 28800 28801 mipmap = mipmaps[ i ]; 28802 state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap ); 28803 28804 } 28805 28806 texture.generateMipmaps = false; 28807 textureProperties.__maxMipLevel = mipmaps.length - 1; 28808 28809 } else { 28810 28811 state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image ); 28812 textureProperties.__maxMipLevel = 0; 28813 28814 } 28815 28816 } 28817 28818 if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { 28819 28820 generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height ); 28821 28822 } 28823 28824 textureProperties.__version = texture.version; 28825 28826 if ( texture.onUpdate ) texture.onUpdate( texture ); 28827 28828 } 28829 28830 // Render targets 28831 28832 // Setup storage for target texture and bind it to correct framebuffer 28833 function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) { 28834 28835 var glFormat = utils.convert( renderTarget.texture.format ); 28836 var glType = utils.convert( renderTarget.texture.type ); 28837 state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); 28838 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); 28839 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); 28840 _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); 28841 28842 } 28843 28844 // Setup storage for internal depth/stencil buffers and bind to correct framebuffer 28845 function setupRenderBufferStorage( renderbuffer, renderTarget ) { 28846 28847 _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); 28848 28849 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { 28850 28851 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height ); 28852 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); 28853 28854 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { 28855 28856 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); 28857 _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); 28858 28859 } else { 28860
28861 // FIXME: We don't support !depth !stencil 28862 _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height ); 28863 28864 } 28865 28866 _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); 28867 28868 } 28869 28870 // Setup resources for a Depth Texture for a FBO (needs an extension) 28871 function setupDepthTexture( framebuffer, renderTarget ) { 28872 28873 var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube ); 28874 if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); 28875 28876 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); 28877 28878 if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) { 28879 28880 throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' ); 28881 28882 } 28883 28884 // upload an empty depth texture with framebuffer size 28885 if ( ! properties.get( renderTarget.depthTexture ).__webglTexture || 28886 renderTarget.depthTexture.image.width !== renderTarget.width || 28887 renderTarget.depthTexture.image.height !== renderTarget.height ) { 28888 28889 renderTarget.depthTexture.image.width = renderTarget.width; 28890 renderTarget.depthTexture.image.height = renderTarget.height; 28891 renderTarget.depthTexture.needsUpdate = true; 28892 28893 } 28894 28895 setTexture2D( renderTarget.depthTexture, 0 ); 28896 28897 var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; 28898 28899 if ( renderTarget.depthTexture.format === DepthFormat ) { 28900 28901 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); 28902 28903 } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { 28904 28905 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); 28906 28907 } else { 28908 28909 throw new Error( 'Unknown depthTexture format' ); 28910 28911 } 28912 28913 } 28914 28915 // Setup GL resources for a non-texture depth buffer 28916 function setupDepthRenderbuffer( renderTarget ) { 28917 28918 var renderTargetProperties = properties.get( renderTarget ); 28919 28920 var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); 28921 28922 if ( renderTarget.depthTexture ) { 28923 28924 if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); 28925 28926 setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); 28927 28928 } else { 28929 28930 if ( isCube ) { 28931 28932 renderTargetProperties.__webglDepthbuffer = []; 28933 28934 for ( var i = 0; i < 6; i ++ ) { 28935 28936 _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); 28937 renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); 28938 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); 28939 28940 } 28941 28942 } else { 28943 28944 _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); 28945 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); 28946 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); 28947 28948 } 28949 28950 } 28951 28952 _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); 28953 28954 } 28955 28956 // Set up GL resources for the render target 28957 function setupRenderTarget( renderTarget ) { 28958 28959 var renderTargetProperties = properties.get( renderTarget ); 28960 var textureProperties = properties.get( renderTarget.texture ); 28961 28962 renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); 28963 28964 textureProperties.__webglTexture = _gl.createTexture(); 28965 28966 info.memory.textures ++; 28967 28968 var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); 28969 var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); 28970 28971 // Setup framebuffer 28972 28973 if ( isCube ) { 28974 28975 renderTargetProperties.__webglFramebuffer = []; 28976 28977 for ( var i = 0; i < 6; i ++ ) { 28978 28979 renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); 28980 28981 } 28982 28983 } else { 28984 28985 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); 28986 28987 } 28988 28989 // Setup color buffer 28990 28991 if ( isCube ) { 28992 28993 state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); 28994 setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo ); 28995 28996 for ( var i = 0; i < 6; i ++ ) { 28997 28998 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); 28999 29000 } 29001 29002 if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { 29003 29004 generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height ); 29005 29006 } 29007 29008 state.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); 29009 29010 } else { 29011
29012 state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); 29013 setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo ); 29014 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D ); 29015 29016 if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { 29017 29018 generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height ); 29019 29020 } 29021 29022 state.bindTexture( _gl.TEXTURE_2D, null ); 29023 29024 } 29025 29026 // Setup depth and stencil buffers 29027 29028 if ( renderTarget.depthBuffer ) { 29029 29030 setupDepthRenderbuffer( renderTarget ); 29031 29032 } 29033 29034 } 29035 29036 function updateRenderTargetMipmap( renderTarget ) { 29037 29038 var texture = renderTarget.texture; 29039 var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); 29040 29041 if ( textureNeedsGenerateMipmaps( texture, isTargetPowerOfTwo ) ) { 29042 29043 var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; 29044 var webglTexture = properties.get( texture ).__webglTexture; 29045 29046 state.bindTexture( target, webglTexture ); 29047 generateMipmap( target, texture, renderTarget.width, renderTarget.height ); 29048 state.bindTexture( target, null ); 29049 29050 } 29051 29052 } 29053 29054 function updateVideoTexture( texture ) { 29055 29056 var id = texture.id; 29057 var frame = info.render.frame; 29058 29059 // Check the last frame we updated the VideoTexture 29060 29061 if ( _videoTextures[ id ] !== frame ) { 29062 29063 _videoTextures[ id ] = frame; 29064 texture.update(); 29065 29066 } 29067 29068 } 29069 29070 this.setTexture2D = setTexture2D; 29071 this.setTextureCube = setTextureCube; 29072 this.setTextureCubeDynamic = setTextureCubeDynamic; 29073 this.setupRenderTarget = setupRenderTarget; 29074 this.updateRenderTargetMipmap = updateRenderTargetMipmap; 29075 29076 } 29077 29078 /** 29079 * @author thespite / http://www.twitter.com/thespite 29080 */ 29081 29082 function WebGLUtils( gl, extensions ) { 29083 29084 function convert( p ) { 29085 29086 var extension; 29087 29088 if ( p === RepeatWrapping ) return gl.REPEAT; 29089 if ( p === ClampToEdgeWrapping ) return gl.CLAMP_TO_EDGE; 29090 if ( p === MirroredRepeatWrapping ) return gl.MIRRORED_REPEAT; 29091 29092 if ( p === NearestFilter ) return gl.NEAREST; 29093 if ( p === NearestMipMapNearestFilter ) return gl.NEAREST_MIPMAP_NEAREST; 29094 if ( p === NearestMipMapLinearFilter ) return gl.NEAREST_MIPMAP_LINEAR; 29095 29096 if ( p === LinearFilter ) return gl.LINEAR; 29097 if ( p === LinearMipMapNearestFilter ) return gl.LINEAR_MIPMAP_NEAREST; 29098 if ( p === LinearMipMapLinearFilter ) return gl.LINEAR_MIPMAP_LINEAR; 29099 29100 if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE; 29101 if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4; 29102 if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1; 29103 if ( p === UnsignedShort565Type ) return gl.UNSIGNED_SHORT_5_6_5; 29104 29105 if ( p === ByteType ) return gl.BYTE; 29106 if ( p === ShortType ) return gl.SHORT; 29107 if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT; 29108 if ( p === IntType ) return gl.INT; 29109 if ( p === UnsignedIntType ) return gl.UNSIGNED_INT; 29110 if ( p === FloatType ) return gl.FLOAT; 29111 29112 if ( p === HalfFloatType ) { 29113 29114 extension = extensions.get( 'OES_texture_half_float' ); 29115 29116 if ( extension !== null ) return extension.HALF_FLOAT_OES; 29117 29118 } 29119 29120 if ( p === AlphaFormat ) return gl.ALPHA; 29121 if ( p === RGBFormat ) return gl.RGB; 29122 if ( p === RGBAFormat ) return gl.RGBA; 29123 if ( p === LuminanceFormat ) return gl.LUMINANCE; 29124 if ( p === LuminanceAlphaFormat ) return gl.LUMINANCE_ALPHA; 29125 if ( p === DepthFormat ) return gl.DEPTH_COMPONENT; 29126 if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL; 29127 29128 if ( p === AddEquation ) return gl.FUNC_ADD; 29129 if ( p === SubtractEquation ) return gl.FUNC_SUBTRACT; 29130 if ( p === ReverseSubtractEquation ) return gl.FUNC_REVERSE_SUBTRACT; 29131 29132 if ( p === ZeroFactor ) return gl.ZERO; 29133 if ( p === OneFactor ) return gl.ONE; 29134 if ( p === SrcColorFactor ) return gl.SRC_COLOR; 29135 if ( p === OneMinusSrcColorFactor ) return gl.ONE_MINUS_SRC_COLOR; 29136 if ( p === SrcAlphaFactor ) return gl.SRC_ALPHA; 29137 if ( p === OneMinusSrcAlphaFactor ) return gl.ONE_MINUS_SRC_ALPHA; 29138 if ( p === DstAlphaFactor ) return gl.DST_ALPHA; 29139 if ( p === OneMinusDstAlphaFactor ) return gl.ONE_MINUS_DST_ALPHA; 29140
29141 if ( p === DstColorFactor ) return gl.DST_COLOR; 29142 if ( p === OneMinusDstColorFactor ) return gl.ONE_MINUS_DST_COLOR; 29143 if ( p === SrcAlphaSaturateFactor ) return gl.SRC_ALPHA_SATURATE; 29144 29145 if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || 29146 p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { 29147 29148 extension = extensions.get( 'WEBGL_compressed_texture_s3tc' ); 29149 29150 if ( extension !== null ) { 29151 29152 if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; 29153 if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; 29154 if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; 29155 if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; 29156 29157 } 29158 29159 } 29160 29161 if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || 29162 p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) { 29163 29164 extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' ); 29165 29166 if ( extension !== null ) { 29167 29168 if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; 29169 if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; 29170 if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; 29171 if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; 29172 29173 } 29174 29175 } 29176 29177 if ( p === RGB_ETC1_Format ) { 29178 29179 extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); 29180 29181 if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL; 29182 29183 } 29184 29185 if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || 29186 p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || 29187 p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || 29188 p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || 29189 p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) { 29190 29191 extension = extensions.get( 'WEBGL_compressed_texture_astc' ); 29192 29193 if ( extension !== null ) { 29194 29195 return p; 29196 29197 } 29198 29199 } 29200 29201 if ( p === MinEquation || p === MaxEquation ) { 29202 29203 extension = extensions.get( 'EXT_blend_minmax' ); 29204 29205 if ( extension !== null ) { 29206 29207 if ( p === MinEquation ) return extension.MIN_EXT; 29208 if ( p === MaxEquation ) return extension.MAX_EXT; 29209 29210 } 29211 29212 } 29213 29214 if ( p === UnsignedInt248Type ) { 29215 29216 extension = extensions.get( 'WEBGL_depth_texture' ); 29217 29218 if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL; 29219 29220 } 29221 29222 return 0; 29223 29224 } 29225 29226 return { convert: convert }; 29227 29228 } 29229 29230 /** 29231 * @author mrdoob / http://mrdoob.com/ 29232 * @author greggman / http://games.greggman.com/ 29233 * @author zz85 / http://www.lab4games.net/zz85/blog 29234 * @author tschw 29235 */ 29236 29237 function PerspectiveCamera( fov, aspect, near, far ) { 29238 29239 Camera.call( this ); 29240 29241 this.type = 'PerspectiveCamera'; 29242 29243 this.fov = fov !== undefined ? fov : 50; 29244 this.zoom = 1; 29245 29246 this.near = near !== undefined ? near : 0.1; 29247 this.far = far !== undefined ? far : 2000; 29248 this.focus = 10; 29249 29250 this.aspect = aspect !== undefined ? aspect : 1; 29251 this.view = null; 29252 29253 this.filmGauge = 35; // width of the film (default in millimeters) 29254 this.filmOffset = 0; // horizontal film offset (same unit as gauge) 29255 29256 this.updateProjectionMatrix(); 29257 29258 } 29259 29260 PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { 29261 29262 constructor: PerspectiveCamera, 29263 29264 isPerspectiveCamera: true, 29265 29266 copy: function ( source, recursive ) { 29267 29268 Camera.prototype.copy.call( this, source, recursive ); 29269 29270 this.fov = source.fov; 29271 this.zoom = source.zoom; 29272 29273 this.near = source.near; 29274 this.far = source.far; 29275 this.focus = source.focus; 29276 29277 this.aspect = source.aspect; 29278 this.view = source.view === null ? null : Object.assign( {}, source.view ); 29279 29280 this.filmGauge = source.filmGauge; 29281 this.filmOffset = source.filmOffset; 29282 29283 return this; 29284 29285 }, 29286
vendor: 5,718 bytes, lines 29287-29523
29287 /** 29288 * Sets the FOV by focal length in respect to the current .filmGauge. 29289 * 29290 * The default film gauge is 35, so that the focal length can be specified for 29291 * a 35mm (full frame) camera. 29292 * 29293 * Values for focal length and film gauge must have the same unit. 29294 */ 29295 setFocalLength: function ( focalLength ) { 29296 29297 // see http://www.bobatkins.com/photography/technical/field_of_view.html 29298 var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; 29299 29300 this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); 29301 this.updateProjectionMatrix(); 29302 29303 }, 29304 29305 /** 29306 * Calculates the focal length from the current .fov and .filmGauge. 29307 */ 29308 getFocalLength: function () { 29309 29310 var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); 29311 29312 return 0.5 * this.getFilmHeight() / vExtentSlope; 29313 29314 }, 29315 29316 getEffectiveFOV: function () { 29317 29318 return _Math.RAD2DEG * 2 * Math.atan( 29319 Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); 29320 29321 }, 29322 29323 getFilmWidth: function () { 29324 29325 // film not completely covered in portrait format (aspect < 1) 29326 return this.filmGauge * Math.min( this.aspect, 1 ); 29327 29328 }, 29329 29330 getFilmHeight: function () { 29331 29332 // film not completely covered in landscape format (aspect > 1) 29333 return this.filmGauge / Math.max( this.aspect, 1 ); 29334 29335 }, 29336 29337 /** 29338 * Sets an offset in a larger frustum. This is useful for multi-window or 29339 * multi-monitor/multi-machine setups. 29340 * 29341 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and 29342 * the monitors are in grid like this 29343 * 29344 * +---+---+---+ 29345 * | A | B | C | 29346 * +---+---+---+ 29347 * | D | E | F | 29348 * +---+---+---+ 29349 * 29350 * then for each monitor you would call it like this 29351 * 29352 * var w = 1920; 29353 * var h = 1080; 29354 * var fullWidth = w * 3; 29355 * var fullHeight = h * 2; 29356 * 29357 * --A-- 29358 * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); 29359 * --B-- 29360 * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); 29361 * --C-- 29362 * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); 29363 * --D-- 29364 * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); 29365 * --E-- 29366 * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); 29367 * --F-- 29368 * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); 29369 * 29370 * Note there is no reason monitors have to be the same size or in a grid. 29371 */ 29372 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { 29373 29374 this.aspect = fullWidth / fullHeight; 29375 29376 if ( this.view === null ) { 29377 29378 this.view = { 29379 enabled: true, 29380 fullWidth: 1, 29381 fullHeight: 1, 29382 offsetX: 0, 29383 offsetY: 0, 29384 width: 1, 29385 height: 1 29386 }; 29387 29388 } 29389 29390 this.view.enabled = true; 29391 this.view.fullWidth = fullWidth; 29392 this.view.fullHeight = fullHeight; 29393 this.view.offsetX = x; 29394 this.view.offsetY = y; 29395 this.view.width = width; 29396 this.view.height = height; 29397 29398 this.updateProjectionMatrix(); 29399 29400 }, 29401 29402 clearViewOffset: function () { 29403 29404 if ( this.view !== null ) { 29405 29406 this.view.enabled = false; 29407 29408 } 29409 29410 this.updateProjectionMatrix(); 29411 29412 }, 29413 29414 updateProjectionMatrix: function () { 29415 29416 var near = this.near, 29417 top = near * Math.tan( 29418 _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, 29419 height = 2 * top, 29420 width = this.aspect * height, 29421 left = - 0.5 * width, 29422 view = this.view; 29423 29424 if ( this.view !== null && this.view.enabled ) { 29425 29426 var fullWidth = view.fullWidth, 29427 fullHeight = view.fullHeight; 29428 29429 left += view.offsetX * width / fullWidth; 29430 top -= view.offsetY * height / fullHeight; 29431 width *= view.width / fullWidth; 29432 height *= view.height / fullHeight; 29433 29434 } 29435 29436 var skew = this.filmOffset; 29437 if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); 29438 29439 this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); 29440 29441 }, 29442 29443 toJSON: function ( meta ) { 29444 29445 var data = Object3D.prototype.toJSON.call( this, meta ); 29446 29447 data.object.fov = this.fov; 29448 data.object.zoom = this.zoom; 29449 29450 data.object.near = this.near; 29451 data.object.far = this.far; 29452 data.object.focus = this.focus; 29453 29454 data.object.aspect = this.aspect; 29455 29456 if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); 29457 29458 data.object.filmGauge = this.filmGauge; 29459 data.object.filmOffset = this.filmOffset; 29460 29461 return data; 29462 29463 } 29464 29465 } ); 29466 29467 /** 29468 * @author mrdoob / http://mrdoob.com/ 29469 */ 29470 29471 function ArrayCamera( array ) { 29472 29473 PerspectiveCamera.call( this ); 29474 29475 this.cameras = array || []; 29476 29477 } 29478 29479 ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), { 29480 29481 constructor: ArrayCamera, 29482 29483 isArrayCamera: true 29484 29485 } ); 29486 29487 /** 29488 * @author mrdoob / http://mrdoob.com/ 29489 */ 29490 29491 function WebVRManager( renderer ) { 29492 29493 var scope = this; 29494 29495 var device = null; 29496 var frameData = null; 29497 29498 var poseTarget = null; 29499 29500 var standingMatrix = new Matrix4(); 29501 var standingMatrixInverse = new Matrix4(); 29502 29503 if ( typeof window !== 'undefined' && 'VRFrameData' in window ) { 29504 29505 frameData = new window.VRFrameData(); 29506 window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); 29507 29508 } 29509 29510 var matrixWorldInverse = new Matrix4(); 29511 var tempQuaternion = new Quaternion(); 29512 var tempPosition = new Vector3(); 29513 29514 var cameraL = new PerspectiveCamera(); 29515 cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 ); 29516 cameraL.layers.enable( 1 ); 29517 29518 var cameraR = new PerspectiveCamera(); 29519 cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 ); 29520 cameraR.layers.enable( 2 ); 29521 29522 var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); 29523 cameraVR.layers.enable( 1 );
29524 cameraVR.layers.enable( 2 ); 29525 29526 // 29527 29528 function isPresenting() { 29529 29530 return device !== null && device.isPresenting === true; 29531 29532 } 29533 29534 var currentSize, currentPixelRatio; 29535 29536 function onVRDisplayPresentChange() { 29537 29538 if ( isPresenting() ) { 29539 29540 var eyeParameters = device.getEyeParameters( 'left' ); 29541 var renderWidth = eyeParameters.renderWidth; 29542 var renderHeight = eyeParameters.renderHeight; 29543 29544 currentPixelRatio = renderer.getPixelRatio(); 29545 currentSize = renderer.getSize(); 29546 29547 renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 ); 29548 29549 animation.start(); 29550 29551 } else if ( scope.enabled ) { 29552 29553 renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio ); 29554 29555 animation.stop(); 29556 29557 } 29558 29559 } 29560 29561 // 29562 29563 this.enabled = false; 29564 this.userHeight = 1.6; 29565 29566 this.getDevice = function () { 29567 29568 return device; 29569 29570 }; 29571 29572 this.setDevice = function ( value ) { 29573 29574 if ( value !== undefined ) device = value; 29575 29576 animation.setContext( value ); 29577 29578 }; 29579 29580 this.setPoseTarget = function ( object ) { 29581 29582 if ( object !== undefined ) poseTarget = object; 29583 29584 }; 29585 29586 this.getCamera = function ( camera ) { 29587 29588 if ( device === null ) return camera; 29589 29590 device.depthNear = camera.near; 29591 device.depthFar = camera.far; 29592 29593 device.getFrameData( frameData ); 29594 29595 // 29596 29597 var stageParameters = device.stageParameters; 29598 29599 if ( stageParameters ) { 29600 29601 standingMatrix.fromArray( stageParameters.sittingToStandingTransform ); 29602 29603 } else { 29604 29605 standingMatrix.makeTranslation( 0, scope.userHeight, 0 ); 29606 29607 } 29608 29609 29610 var pose = frameData.pose; 29611 var poseObject = poseTarget !== null ? poseTarget : camera; 29612 29613 // We want to manipulate poseObject by its position and quaternion components since users may rely on them. 29614 poseObject.matrix.copy( standingMatrix ); 29615 poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale ); 29616 29617 if ( pose.orientation !== null ) { 29618 29619 tempQuaternion.fromArray( pose.orientation ); 29620 poseObject.quaternion.multiply( tempQuaternion ); 29621 29622 } 29623 29624 if ( pose.position !== null ) { 29625 29626 tempQuaternion.setFromRotationMatrix( standingMatrix ); 29627 tempPosition.fromArray( pose.position ); 29628 tempPosition.applyQuaternion( tempQuaternion ); 29629 poseObject.position.add( tempPosition ); 29630 29631 } 29632 29633 poseObject.updateMatrixWorld(); 29634 29635 if ( device.isPresenting === false ) return camera; 29636 29637 // 29638 29639 cameraL.near = camera.near; 29640 cameraR.near = camera.near; 29641 29642 cameraL.far = camera.far; 29643 cameraR.far = camera.far; 29644 29645 cameraVR.matrixWorld.copy( camera.matrixWorld ); 29646 cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse ); 29647 29648 cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); 29649 cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); 29650 29651 // TODO (mrdoob) Double check this code 29652 29653 standingMatrixInverse.getInverse( standingMatrix ); 29654 29655 cameraL.matrixWorldInverse.multiply( standingMatrixInverse ); 29656 cameraR.matrixWorldInverse.multiply( standingMatrixInverse ); 29657 29658 var parent = poseObject.parent; 29659 29660 if ( parent !== null ) { 29661 29662 matrixWorldInverse.getInverse( parent.matrixWorld ); 29663 29664 cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); 29665 cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); 29666 29667 } 29668 29669 // envMap and Mirror needs camera.matrixWorld 29670 29671 cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse ); 29672 cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse ); 29673 29674 cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); 29675 cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); 29676 29677 // HACK (mrdoob) 29678 // https://github.com/w3c/webvr/issues/203 29679 29680 cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); 29681 29682 // 29683 29684 var layers = device.getLayers(); 29685 29686 if ( layers.length ) { 29687 29688 var layer = layers[ 0 ]; 29689 29690 if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) { 29691 29692 cameraL.bounds.fromArray( layer.leftBounds ); 29693 29694 } 29695 29696 if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) { 29697 29698 cameraR.bounds.fromArray( layer.rightBounds ); 29699 29700 } 29701 29702 } 29703 29704 return cameraVR; 29705 29706 }; 29707
29708 this.getStandingMatrix = function () { 29709 29710 return standingMatrix; 29711 29712 }; 29713 29714 this.isPresenting = isPresenting; 29715 29716 // Animation Loop 29717 29718 var animation = new WebGLAnimation(); 29719 29720 this.setAnimationLoop = function ( callback ) { 29721 29722 animation.setAnimationLoop( callback ); 29723 29724 }; 29725 29726 this.submitFrame = function () { 29727 29728 if ( isPresenting() ) device.submitFrame(); 29729 29730 }; 29731 29732 this.dispose = function () { 29733 29734 if ( typeof window !== 'undefined' ) { 29735 29736 window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange ); 29737 29738 } 29739 29740 }; 29741 29742 } 29743 29744 /** 29745 * @author mrdoob / http://mrdoob.com/ 29746 */ 29747 29748 function WebXRManager( renderer ) { 29749 29750 var gl = renderer.context; 29751 29752 var device = null; 29753 var session = null; 29754 29755 var frameOfRef = null; 29756 29757 var pose = null; 29758 29759 function isPresenting() { 29760 29761 return session !== null && frameOfRef !== null; 29762 29763 } 29764 29765 // 29766 29767 var cameraL = new PerspectiveCamera(); 29768 cameraL.layers.enable( 1 ); 29769 cameraL.viewport = new Vector4(); 29770 29771 var cameraR = new PerspectiveCamera(); 29772 cameraR.layers.enable( 2 ); 29773 cameraR.viewport = new Vector4(); 29774 29775 var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); 29776 cameraVR.layers.enable( 1 ); 29777 cameraVR.layers.enable( 2 ); 29778 29779 // 29780 29781 this.enabled = false; 29782 29783 this.getDevice = function () { 29784 29785 return device; 29786 29787 }; 29788 29789 this.setDevice = function ( value ) { 29790 29791 if ( value !== undefined ) device = value; 29792 29793 gl.setCompatibleXRDevice( value ); 29794 29795 }; 29796 29797 // 29798 29799 this.setSession = function ( value, options ) { 29800 29801 session = value; 29802 29803 if ( session !== null ) { 29804 29805 session.addEventListener( 'end', function () { 29806 29807 renderer.setFramebuffer( null ); 29808 animation.stop(); 29809 29810 } ); 29811 29812 session.baseLayer = new XRWebGLLayer( session, gl ); 29813 session.requestFrameOfReference( options.frameOfReferenceType ).then( function ( value ) { 29814 29815 frameOfRef = value; 29816 29817 renderer.setFramebuffer( session.baseLayer.framebuffer ); 29818 29819 animation.setContext( session ); 29820 animation.start(); 29821 29822 } ); 29823 29824 } 29825 29826 }; 29827 29828 function updateCamera( camera, parent ) { 29829 29830 if ( parent === null ) { 29831 29832 camera.matrixWorld.copy( camera.matrix ); 29833 29834 } else { 29835 29836 camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix ); 29837 29838 } 29839 29840 camera.matrixWorldInverse.getInverse( camera.matrixWorld ); 29841 29842 } 29843 29844 this.getCamera = function ( camera ) { 29845 29846 if ( isPresenting() ) { 29847 29848 var parent = camera.parent; 29849 var cameras = cameraVR.cameras; 29850 29851 // apply camera.parent to cameraVR 29852 29853 updateCamera( cameraVR, parent ); 29854 29855 for ( var i = 0; i < cameras.length; i ++ ) { 29856 29857 updateCamera( cameras[ i ], parent ); 29858 29859 } 29860 29861 // update camera and its children 29862 29863 camera.matrixWorld.copy( cameraVR.matrixWorld ); 29864 29865 var children = camera.children; 29866 29867 for ( var i = 0, l = children.length; i < l; i ++ ) { 29868 29869 children[ i ].updateMatrixWorld( true ); 29870 29871 } 29872 29873 return cameraVR; 29874 29875 } 29876 29877 return camera; 29878 29879 }; 29880 29881 this.isPresenting = isPresenting; 29882 29883 // Animation Loop 29884 29885 var onAnimationFrameCallback = null; 29886 29887 function onAnimationFrame( time, frame ) { 29888 29889 pose = frame.getDevicePose( frameOfRef ); 29890 29891 var layer = session.baseLayer; 29892 var views = frame.views; 29893 29894 for ( var i = 0; i < views.length; i ++ ) { 29895 29896 var view = views[ i ]; 29897 var viewport = layer.getViewport( view ); 29898 var viewMatrix = pose.getViewMatrix( view ); 29899 29900 var camera = cameraVR.cameras[ i ]; 29901 camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); 29902 camera.projectionMatrix.fromArray( view.projectionMatrix ); 29903 camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); 29904 29905 if ( i === 0 ) { 29906 29907 cameraVR.matrix.copy( camera.matrix ); 29908 29909 // HACK (mrdoob) 29910 // https://github.com/w3c/webvr/issues/203 29911 29912 cameraVR.projectionMatrix.copy( camera.projectionMatrix ); 29913 29914 } 29915 29916 } 29917 29918 if ( onAnimationFrameCallback ) onAnimationFrameCallback(); 29919 29920 } 29921 29922 var animation = new WebGLAnimation(); 29923 animation.setAnimationLoop( onAnimationFrame ); 29924 29925 this.setAnimationLoop = function ( callback ) { 29926 29927 onAnimationFrameCallback = callback; 29928 29929 }; 29930 29931 // DEPRECATED 29932
29933 this.getStandingMatrix = function () { 29934 29935 console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); 29936 return new THREE.Matrix4(); 29937 29938 }; 29939 29940 this.submitFrame = function () {}; 29941 29942 } 29943 29944 /** 29945 * @author supereggbert / http://www.paulbrunt.co.uk/ 29946 * @author mrdoob / http://mrdoob.com/ 29947 * @author alteredq / http://alteredqualia.com/ 29948 * @author szimek / https://github.com/szimek/ 29949 * @author tschw 29950 */ 29951 29952 function WebGLRenderer( parameters ) { 29953 29954 console.log( 'THREE.WebGLRenderer', REVISION ); 29955 29956 parameters = parameters || {}; 29957 29958 var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ), 29959 _context = parameters.context !== undefined ? parameters.context : null, 29960 29961 _alpha = parameters.alpha !== undefined ? parameters.alpha : false, 29962 _depth = parameters.depth !== undefined ? parameters.depth : true, 29963 _stencil = parameters.stencil !== undefined ? parameters.stencil : true, 29964 _antialias = parameters.antialias !== undefined ? parameters.antialias : false, 29965 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, 29966 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, 29967 _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default'; 29968 29969 var currentRenderList = null; 29970 var currentRenderState = null; 29971 29972 // public properties 29973 29974 this.domElement = _canvas; 29975 this.context = null; 29976 29977 // clearing 29978 29979 this.autoClear = true; 29980 this.autoClearColor = true; 29981 this.autoClearDepth = true; 29982 this.autoClearStencil = true; 29983 29984 // scene graph 29985 29986 this.sortObjects = true; 29987 29988 // user-defined clipping 29989 29990 this.clippingPlanes = []; 29991 this.localClippingEnabled = false; 29992 29993 // physically based shading 29994 29995 this.gammaFactor = 2.0; // for backwards compatibility 29996 this.gammaInput = false; 29997 this.gammaOutput = false; 29998 29999 // physical lights 30000 30001 this.physicallyCorrectLights = false; 30002 30003 // tone mapping 30004 30005 this.toneMapping = LinearToneMapping; 30006 this.toneMappingExposure = 1.0; 30007 this.toneMappingWhitePoint = 1.0; 30008 30009 // morphs 30010 30011 this.maxMorphTargets = 8; 30012 this.maxMorphNormals = 4; 30013 30014 // internal properties 30015 30016 var _this = this, 30017 30018 _isContextLost = false, 30019 30020 // internal state cache 30021 30022 _framebuffer = null, 30023 30024 _currentRenderTarget = null, 30025 _currentFramebuffer = null, 30026 _currentMaterialId = - 1, 30027 _currentGeometryProgram = '', 30028 30029 _currentCamera = null, 30030 _currentArrayCamera = null, 30031 30032 _currentViewport = new Vector4(), 30033 _currentScissor = new Vector4(), 30034 _currentScissorTest = null, 30035 30036 // 30037 30038 _usedTextureUnits = 0, 30039 30040 // 30041 30042 _width = _canvas.width, 30043 _height = _canvas.height, 30044 30045 _pixelRatio = 1, 30046 30047 _viewport = new Vector4( 0, 0, _width, _height ), 30048 _scissor = new Vector4( 0, 0, _width, _height ), 30049 _scissorTest = false, 30050 30051 // frustum 30052 30053 _frustum = new Frustum(), 30054 30055 // clipping 30056 30057 _clipping = new WebGLClipping(), 30058 _clippingEnabled = false, 30059 _localClippingEnabled = false, 30060 30061 // camera matrices cache 30062 30063 _projScreenMatrix = new Matrix4(), 30064 30065 _vector3 = new Vector3(); 30066 30067 function getTargetPixelRatio() { 30068 30069 return _currentRenderTarget === null ? _pixelRatio : 1; 30070 30071 } 30072 30073 // initialize 30074 30075 var _gl; 30076 30077 try { 30078 30079 var contextAttributes = { 30080 alpha: _alpha, 30081 depth: _depth, 30082 stencil: _stencil, 30083 antialias: _antialias, 30084 premultipliedAlpha: _premultipliedAlpha, 30085 preserveDrawingBuffer: _preserveDrawingBuffer, 30086 powerPreference: _powerPreference 30087 }; 30088 30089 // event listeners must be registered before WebGL context is created, see #12753 30090 30091 _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); 30092 _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false ); 30093 30094 _gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes ); 30095 30096 if ( _gl === null ) { 30097 30098 if ( _canvas.getContext( 'webgl' ) !== null ) { 30099 30100 throw new Error( 'Error creating WebGL context with your selected attributes.' ); 30101 30102 } else { 30103
30104 throw new Error( 'Error creating WebGL context.' ); 30105 30106 } 30107 30108 } 30109 30110 // Some experimental-webgl implementations do not have getShaderPrecisionFormat 30111 30112 if ( _gl.getShaderPrecisionFormat === undefined ) { 30113 30114 _gl.getShaderPrecisionFormat = function () { 30115 30116 return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; 30117 30118 }; 30119 30120 } 30121 30122 } catch ( error ) { 30123 30124 console.error( 'THREE.WebGLRenderer: ' + error.message ); 30125 30126 } 30127 30128 var extensions, capabilities, state, info; 30129 var properties, textures, attributes, geometries, objects; 30130 var programCache, renderLists, renderStates; 30131 30132 var background, morphtargets, bufferRenderer, indexedBufferRenderer; 30133 var spriteRenderer; 30134 30135 var utils; 30136 30137 function initGLContext() { 30138 30139 extensions = new WebGLExtensions( _gl ); 30140 extensions.get( 'WEBGL_depth_texture' ); 30141 extensions.get( 'OES_texture_float' ); 30142 extensions.get( 'OES_texture_float_linear' ); 30143 extensions.get( 'OES_texture_half_float' ); 30144 extensions.get( 'OES_texture_half_float_linear' ); 30145 extensions.get( 'OES_standard_derivatives' ); 30146 extensions.get( 'OES_element_index_uint' ); 30147 extensions.get( 'ANGLE_instanced_arrays' ); 30148 30149 utils = new WebGLUtils( _gl, extensions ); 30150 30151 capabilities = new WebGLCapabilities( _gl, extensions, parameters ); 30152 30153 state = new WebGLState( _gl, extensions, utils ); 30154 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); 30155 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); 30156 30157 info = new WebGLInfo( _gl ); 30158 properties = new WebGLProperties(); 30159 textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); 30160 attributes = new WebGLAttributes( _gl ); 30161 geometries = new WebGLGeometries( _gl, attributes, info ); 30162 objects = new WebGLObjects( geometries, info ); 30163 morphtargets = new WebGLMorphtargets( _gl ); 30164 programCache = new WebGLPrograms( _this, extensions, capabilities ); 30165 renderLists = new WebGLRenderLists(); 30166 renderStates = new WebGLRenderStates(); 30167 30168 background = new WebGLBackground( _this, state, objects, _premultipliedAlpha ); 30169 30170 bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info ); 30171 indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info ); 30172 30173 spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities ); 30174 30175 info.programs = programCache.programs; 30176 30177 _this.context = _gl; 30178 _this.capabilities = capabilities; 30179 _this.extensions = extensions; 30180 _this.properties = properties; 30181 _this.renderLists = renderLists; 30182 _this.state = state; 30183 _this.info = info; 30184 30185 } 30186 30187 initGLContext(); 30188 30189 // vr 30190 30191 var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this ); 30192 30193 this.vr = vr; 30194 30195 // shadow map 30196 30197 var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize ); 30198 30199 this.shadowMap = shadowMap; 30200 30201 // API 30202 30203 this.getContext = function () { 30204 30205 return _gl; 30206 30207 }; 30208 30209 this.getContextAttributes = function () { 30210 30211 return _gl.getContextAttributes(); 30212 30213 }; 30214 30215 this.forceContextLoss = function () { 30216 30217 var extension = extensions.get( 'WEBGL_lose_context' ); 30218 if ( extension ) extension.loseContext(); 30219 30220 }; 30221 30222 this.forceContextRestore = function () { 30223 30224 var extension = extensions.get( 'WEBGL_lose_context' ); 30225 if ( extension ) extension.restoreContext(); 30226 30227 }; 30228 30229 this.getPixelRatio = function () { 30230 30231 return _pixelRatio; 30232 30233 }; 30234 30235 this.setPixelRatio = function ( value ) { 30236 30237 if ( value === undefined ) return; 30238 30239 _pixelRatio = value; 30240 30241 this.setSize( _width, _height, false ); 30242 30243 }; 30244 30245 this.getSize = function () { 30246 30247 return { 30248 width: _width, 30249 height: _height 30250 }; 30251 30252 }; 30253 30254 this.setSize = function ( width, height, updateStyle ) { 30255 30256 if ( vr.isPresenting() ) { 30257 30258 console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); 30259 return; 30260 30261 } 30262 30263 _width = width; 30264 _height = height; 30265 30266 _canvas.width = width * _pixelRatio; 30267 _canvas.height = height * _pixelRatio; 30268 30269 if ( updateStyle !== false ) { 30270 30271 _canvas.style.width = width + 'px'; 30272 _canvas.style.height = height + 'px'; 30273 30274 } 30275 30276 this.setViewport( 0, 0, width, height ); 30277 30278 }; 30279 30280 this.getDrawingBufferSize = function () { 30281 30282 return { 30283 width: _width * _pixelRatio, 30284 height: _height * _pixelRatio 30285 }; 30286 30287 }; 30288 30289 this.setDrawingBufferSize = function ( width, height, pixelRatio ) { 30290 30291 _width = width; 30292 _height = height; 30293 30294 _pixelRatio = pixelRatio; 30295 30296 _canvas.width = width * pixelRatio; 30297 _canvas.height = height * pixelRatio; 30298 30299 this.setViewport( 0, 0, width, height ); 30300 30301 }; 30302 30303 this.getCurrentViewport = function () { 30304 30305 return _currentViewport; 30306 30307 }; 30308 30309 this.setViewport = function ( x, y, width, height ) { 30310 30311 _viewport.set( x, _height - y - height, width, height ); 30312 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); 30313 30314 }; 30315 30316 this.setScissor = function ( x, y, width, height ) { 30317 30318 _scissor.set( x, _height - y - height, width, height ); 30319 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); 30320 30321 }; 30322 30323 this.setScissorTest = function ( boolean ) { 30324 30325 state.setScissorTest( _scissorTest = boolean ); 30326 30327 }; 30328 30329 // Clearing 30330 30331 this.getClearColor = function () { 30332 30333 return background.getClearColor(); 30334 30335 }; 30336 30337 this.setClearColor = function () { 30338 30339 background.setClearColor.apply( background, arguments ); 30340 30341 }; 30342 30343 this.getClearAlpha = function () { 30344 30345 return background.getClearAlpha(); 30346 30347 }; 30348 30349 this.setClearAlpha = function () { 30350 30351 background.setClearAlpha.apply( background, arguments ); 30352 30353 }; 30354 30355 this.clear = function ( color, depth, stencil ) { 30356 30357 var bits = 0; 30358 30359 if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT; 30360 if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT; 30361 if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT; 30362 30363 _gl.clear( bits ); 30364 30365 }; 30366 30367 this.clearColor = function () { 30368 30369 this.clear( true, false, false ); 30370 30371 }; 30372 30373 this.clearDepth = function () { 30374 30375 this.clear( false, true, false ); 30376 30377 }; 30378 30379 this.clearStencil = function () { 30380 30381 this.clear( false, false, true ); 30382 30383 }; 30384 30385 this.clearTarget = function ( renderTarget, color, depth, stencil ) { 30386 30387 this.setRenderTarget( renderTarget ); 30388 this.clear( color, depth, stencil ); 30389 30390 }; 30391 30392 // 30393 30394 this.dispose = function () { 30395 30396 _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); 30397 _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); 30398 30399 renderLists.dispose(); 30400 renderStates.dispose(); 30401 properties.dispose(); 30402 objects.dispose(); 30403 30404 vr.dispose(); 30405 30406 animation.stop(); 30407 30408 }; 30409 30410 // Events 30411 30412 function onContextLost( event ) { 30413 30414 event.preventDefault(); 30415 30416 console.log( 'THREE.WebGLRenderer: Context Lost.' ); 30417 30418 _isContextLost = true; 30419 30420 } 30421 30422 function onContextRestore( /* event */ ) { 30423 30424 console.log( 'THREE.WebGLRenderer: Context Restored.' ); 30425 30426 _isContextLost = false;
30427 30428 initGLContext(); 30429 30430 } 30431 30432 function onMaterialDispose( event ) { 30433 30434 var material = event.target; 30435 30436 material.removeEventListener( 'dispose', onMaterialDispose ); 30437 30438 deallocateMaterial( material ); 30439 30440 } 30441 30442 // Buffer deallocation 30443 30444 function deallocateMaterial( material ) { 30445 30446 releaseMaterialProgramReference( material ); 30447 30448 properties.remove( material ); 30449 30450 } 30451 30452 30453 function releaseMaterialProgramReference( material ) { 30454 30455 var programInfo = properties.get( material ).program; 30456 30457 material.program = undefined; 30458 30459 if ( programInfo !== undefined ) { 30460 30461 programCache.releaseProgram( programInfo ); 30462 30463 } 30464 30465 } 30466 30467 // Buffer rendering 30468 30469 function renderObjectImmediate( object, program, material ) { 30470 30471 object.render( function ( object ) { 30472 30473 _this.renderBufferImmediate( object, program, material ); 30474 30475 } ); 30476 30477 } 30478 30479 this.renderBufferImmediate = function ( object, program, material ) { 30480 30481 state.initAttributes(); 30482 30483 var buffers = properties.get( object ); 30484 30485 if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer(); 30486 if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer(); 30487 if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer(); 30488 if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer(); 30489 30490 var programAttributes = program.getAttributes(); 30491 30492 if ( object.hasPositions ) { 30493 30494 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position ); 30495 _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); 30496 30497 state.enableAttribute( programAttributes.position ); 30498 _gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 ); 30499 30500 } 30501 30502 if ( object.hasNormals ) { 30503 30504 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); 30505 30506 if ( ! material.isMeshPhongMaterial && 30507 ! material.isMeshStandardMaterial && 30508 ! material.isMeshNormalMaterial && 30509 material.flatShading === true ) { 30510 30511 for ( var i = 0, l = object.count * 3; i < l; i += 9 ) { 30512 30513 var array = object.normalArray; 30514 30515 var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3; 30516 var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3; 30517 var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3; 30518 30519 array[ i + 0 ] = nx; 30520 array[ i + 1 ] = ny; 30521 array[ i + 2 ] = nz; 30522 30523 array[ i + 3 ] = nx; 30524 array[ i + 4 ] = ny; 30525 array[ i + 5 ] = nz; 30526 30527 array[ i + 6 ] = nx; 30528 array[ i + 7 ] = ny; 30529 array[ i + 8 ] = nz; 30530 30531 } 30532 30533 } 30534 30535 _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); 30536 30537 state.enableAttribute( programAttributes.normal ); 30538 30539 _gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 ); 30540 30541 } 30542 30543 if ( object.hasUvs && material.map ) { 30544 30545 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv ); 30546 _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); 30547 30548 state.enableAttribute( programAttributes.uv ); 30549 30550 _gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 ); 30551 30552 } 30553 30554 if ( object.hasColors && material.vertexColors !== NoColors ) { 30555 30556 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color ); 30557 _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); 30558 30559 state.enableAttribute( programAttributes.color ); 30560 30561 _gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 ); 30562 30563 } 30564 30565 state.disableUnusedAttributes(); 30566 30567 _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); 30568 30569 object.count = 0; 30570 30571 }; 30572 30573 this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { 30574 30575 var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 ); 30576 30577 state.setMaterial( material, frontFaceCW ); 30578 30579 var program = setProgram( camera, fog, material, object ); 30580 var geometryProgram = geometry.id + '_' + program.id + '_' + ( material.wireframe === true ); 30581 30582 var updateBuffers = false; 30583 30584 if ( geometryProgram !== _currentGeometryProgram ) { 30585 30586 _currentGeometryProgram = geometryProgram; 30587 updateBuffers = true; 30588 30589 } 30590 30591 if ( object.morphTargetInfluences ) { 30592 30593 morphtargets.update( object, geometry, material, program ); 30594 30595 updateBuffers = true; 30596 30597 } 30598 30599 // 30600 30601 var index = geometry.index; 30602 var position = geometry.attributes.position; 30603 var rangeFactor = 1; 30604 30605 if ( material.wireframe === true ) { 30606 30607 index = geometries.getWireframeAttribute( geometry ); 30608 rangeFactor = 2; 30609 30610 } 30611 30612 var attribute; 30613 var renderer = bufferRenderer; 30614 30615 if ( index !== null ) { 30616 30617 attribute = attributes.get( index ); 30618 30619 renderer = indexedBufferRenderer; 30620 renderer.setIndex( attribute ); 30621 30622 } 30623 30624 if ( updateBuffers ) { 30625 30626 setupVertexAttributes( material, program, geometry ); 30627 30628 if ( index !== null ) { 30629 30630 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer ); 30631 30632 } 30633 30634 } 30635 30636 // 30637 30638 var dataCount = Infinity; 30639 30640 if ( index !== null ) { 30641 30642 dataCount = index.count; 30643 30644 } else if ( position !== undefined ) { 30645 30646 dataCount = position.count; 30647 30648 } 30649 30650 var rangeStart = geometry.drawRange.start * rangeFactor; 30651 var rangeCount = geometry.drawRange.count * rangeFactor; 30652 30653 var groupStart = group !== null ? group.start * rangeFactor : 0; 30654 var groupCount = group !== null ? group.count * rangeFactor : Infinity; 30655 30656 var drawStart = Math.max( rangeStart, groupStart ); 30657 var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; 30658 30659 var drawCount = Math.max( 0, drawEnd - drawStart + 1 ); 30660 30661 if ( drawCount === 0 ) return; 30662 30663 // 30664 30665 if ( object.isMesh ) { 30666 30667 if ( material.wireframe === true ) { 30668 30669 state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); 30670 renderer.setMode( _gl.LINES ); 30671 30672 } else { 30673
30674 switch ( object.drawMode ) { 30675 30676 case TrianglesDrawMode: 30677 renderer.setMode( _gl.TRIANGLES ); 30678 break; 30679 30680 case TriangleStripDrawMode: 30681 renderer.setMode( _gl.TRIANGLE_STRIP ); 30682 break; 30683 30684 case TriangleFanDrawMode: 30685 renderer.setMode( _gl.TRIANGLE_FAN ); 30686 break; 30687 30688 } 30689 30690 } 30691 30692 30693 } else if ( object.isLine ) { 30694 30695 var lineWidth = material.linewidth; 30696 30697 if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material 30698 30699 state.setLineWidth( lineWidth * getTargetPixelRatio() ); 30700 30701 if ( object.isLineSegments ) { 30702 30703 renderer.setMode( _gl.LINES ); 30704 30705 } else if ( object.isLineLoop ) { 30706 30707 renderer.setMode( _gl.LINE_LOOP ); 30708 30709 } else { 30710 30711 renderer.setMode( _gl.LINE_STRIP ); 30712 30713 } 30714 30715 } else if ( object.isPoints ) { 30716 30717 renderer.setMode( _gl.POINTS ); 30718 30719 } 30720 30721 if ( geometry && geometry.isInstancedBufferGeometry ) { 30722 30723 if ( geometry.maxInstancedCount > 0 ) { 30724 30725 renderer.renderInstances( geometry, drawStart, drawCount ); 30726 30727 } 30728 30729 } else { 30730 30731 renderer.render( drawStart, drawCount ); 30732 30733 } 30734 30735 }; 30736 30737 function setupVertexAttributes( material, program, geometry ) { 30738 30739 if ( geometry && geometry.isInstancedBufferGeometry ) { 30740 30741 if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { 30742 30743 console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); 30744 return; 30745 30746 } 30747 30748 } 30749 30750 state.initAttributes(); 30751 30752 var geometryAttributes = geometry.attributes; 30753 30754 var programAttributes = program.getAttributes(); 30755 30756 var materialDefaultAttributeValues = material.defaultAttributeValues; 30757 30758 for ( var name in programAttributes ) { 30759 30760 var programAttribute = programAttributes[ name ]; 30761 30762 if ( programAttribute >= 0 ) { 30763 30764 var geometryAttribute = geometryAttributes[ name ]; 30765 30766 if ( geometryAttribute !== undefined ) { 30767 30768 var normalized = geometryAttribute.normalized; 30769 var size = geometryAttribute.itemSize; 30770 30771 var attribute = attributes.get( geometryAttribute ); 30772 30773 // TODO Attribute may not be available on context restore 30774 30775 if ( attribute === undefined ) continue; 30776 30777 var buffer = attribute.buffer; 30778 var type = attribute.type; 30779 var bytesPerElement = attribute.bytesPerElement; 30780 30781 if ( geometryAttribute.isInterleavedBufferAttribute ) { 30782 30783 var data = geometryAttribute.data; 30784 var stride = data.stride; 30785 var offset = geometryAttribute.offset; 30786 30787 if ( data && data.isInstancedInterleavedBuffer ) { 30788 30789 state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute ); 30790 30791 if ( geometry.maxInstancedCount === undefined ) { 30792 30793 geometry.maxInstancedCount = data.meshPerAttribute * data.count; 30794 30795 } 30796 30797 } else { 30798 30799 state.enableAttribute( programAttribute ); 30800 30801 } 30802 30803 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); 30804 _gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement ); 30805 30806 } else { 30807 30808 if ( geometryAttribute.isInstancedBufferAttribute ) { 30809 30810 state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute ); 30811 30812 if ( geometry.maxInstancedCount === undefined ) { 30813 30814 geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; 30815 30816 } 30817 30818 } else { 30819 30820 state.enableAttribute( programAttribute ); 30821 30822 } 30823 30824 _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); 30825 _gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 ); 30826 30827 } 30828 30829 } else if ( materialDefaultAttributeValues !== undefined ) { 30830 30831 var value = materialDefaultAttributeValues[ name ]; 30832 30833 if ( value !== undefined ) { 30834 30835 switch ( value.length ) { 30836 30837 case 2: 30838 _gl.vertexAttrib2fv( programAttribute, value ); 30839 break; 30840 30841 case 3: 30842 _gl.vertexAttrib3fv( programAttribute, value ); 30843 break; 30844 30845 case 4: 30846 _gl.vertexAttrib4fv( programAttribute, value ); 30847 break; 30848 30849 default: 30850 _gl.vertexAttrib1fv( programAttribute, value ); 30851 30852 } 30853 30854 } 30855 30856 } 30857 30858 } 30859 30860 } 30861 30862 state.disableUnusedAttributes(); 30863 30864 } 30865 30866 // Compile 30867 30868 this.compile = function ( scene, camera ) { 30869 30870 currentRenderState = renderStates.get( scene, camera );
30871 currentRenderState.init(); 30872 30873 scene.traverse( function ( object ) { 30874 30875 if ( object.isLight ) { 30876 30877 currentRenderState.pushLight( object ); 30878 30879 if ( object.castShadow ) { 30880 30881 currentRenderState.pushShadow( object ); 30882 30883 } 30884 30885 } 30886 30887 } ); 30888 30889 currentRenderState.setupLights( camera ); 30890 30891 scene.traverse( function ( object ) { 30892 30893 if ( object.material ) { 30894 30895 if ( Array.isArray( object.material ) ) { 30896 30897 for ( var i = 0; i < object.material.length; i ++ ) { 30898 30899 initMaterial( object.material[ i ], scene.fog, object ); 30900 30901 } 30902 30903 } else { 30904 30905 initMaterial( object.material, scene.fog, object ); 30906 30907 } 30908 30909 } 30910 30911 } ); 30912 30913 }; 30914 30915 // Animation Loop 30916 30917 var onAnimationFrameCallback = null; 30918 30919 function onAnimationFrame() { 30920 30921 if ( vr.isPresenting() ) return; 30922 if ( onAnimationFrameCallback ) onAnimationFrameCallback(); 30923 30924 } 30925 30926 var animation = new WebGLAnimation(); 30927 animation.setAnimationLoop( onAnimationFrame ); 30928 animation.setContext( window ); 30929 30930 this.setAnimationLoop = function ( callback ) { 30931 30932 onAnimationFrameCallback = callback; 30933 vr.setAnimationLoop( callback ); 30934 30935 animation.start(); 30936 30937 }; 30938 30939 // Rendering 30940 30941 this.render = function ( scene, camera, renderTarget, forceClear ) { 30942 30943 if ( ! ( camera && camera.isCamera ) ) { 30944 30945 console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); 30946 return; 30947 30948 } 30949 30950 if ( _isContextLost ) return; 30951 30952 // reset caching for this frame 30953 30954 _currentGeometryProgram = ''; 30955 _currentMaterialId = - 1; 30956 _currentCamera = null; 30957 30958 // update scene graph 30959 30960 if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); 30961 30962 // update camera matrices and frustum 30963 30964 if ( camera.parent === null ) camera.updateMatrixWorld(); 30965 30966 if ( vr.enabled ) { 30967 30968 camera = vr.getCamera( camera ); 30969 30970 } 30971 30972 // 30973 30974 currentRenderState = renderStates.get( scene, camera ); 30975 currentRenderState.init(); 30976 30977 scene.onBeforeRender( _this, scene, camera, renderTarget ); 30978 30979 _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); 30980 _frustum.setFromMatrix( _projScreenMatrix ); 30981 30982 _localClippingEnabled = this.localClippingEnabled; 30983 _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); 30984 30985 currentRenderList = renderLists.get( scene, camera ); 30986 currentRenderList.init(); 30987 30988 projectObject( scene, camera, _this.sortObjects ); 30989 30990 if ( _this.sortObjects === true ) { 30991 30992 currentRenderList.sort(); 30993 30994 } 30995 30996 // 30997 30998 if ( _clippingEnabled ) _clipping.beginShadows(); 30999 31000 var shadowsArray = currentRenderState.state.shadowsArray; 31001 31002 shadowMap.render( shadowsArray, scene, camera ); 31003 31004 currentRenderState.setupLights( camera ); 31005 31006 if ( _clippingEnabled ) _clipping.endShadows(); 31007 31008 // 31009 31010 if ( this.info.autoReset ) this.info.reset(); 31011 31012 if ( renderTarget === undefined ) { 31013 31014 renderTarget = null; 31015 31016 } 31017 31018 this.setRenderTarget( renderTarget ); 31019 31020 // 31021 31022 background.render( currentRenderList, scene, camera, forceClear ); 31023 31024 // render scene 31025 31026 var opaqueObjects = currentRenderList.opaque; 31027 var transparentObjects = currentRenderList.transparent; 31028 31029 if ( scene.overrideMaterial ) { 31030 31031 var overrideMaterial = scene.overrideMaterial; 31032 31033 if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial ); 31034 if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial ); 31035 31036 } else { 31037 31038 // opaque pass (front-to-back order) 31039 31040 if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera ); 31041 31042 // transparent pass (back-to-front order) 31043 31044 if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera ); 31045 31046 } 31047 31048 // custom renderers 31049 31050 var spritesArray = currentRenderState.state.spritesArray; 31051 31052 spriteRenderer.render( spritesArray, scene, camera ); 31053 31054 // Generate mipmap if we're using any kind of mipmap filtering 31055 31056 if ( renderTarget ) { 31057 31058 textures.updateRenderTargetMipmap( renderTarget ); 31059 31060 } 31061 31062 // Ensure depth buffer writing is enabled so it can be cleared on next render 31063 31064 state.buffers.depth.setTest( true ); 31065 state.buffers.depth.setMask( true ); 31066 state.buffers.color.setMask( true ); 31067 31068 state.setPolygonOffset( false ); 31069 31070 scene.onAfterRender( _this, scene, camera ); 31071 31072 if ( vr.enabled ) { 31073 31074 vr.submitFrame(); 31075 31076 } 31077 31078 // _gl.finish(); 31079 31080 currentRenderList = null; 31081 currentRenderState = null; 31082 31083 }; 31084 31085 /* 31086 // TODO Duplicated code (Frustum) 31087 31088 var _sphere = new Sphere(); 31089 31090 function isObjectViewable( object ) { 31091 31092 var geometry = object.geometry; 31093 31094 if ( geometry.boundingSphere === null ) 31095 geometry.computeBoundingSphere(); 31096 31097 _sphere.copy( geometry.boundingSphere ). 31098 applyMatrix4( object.matrixWorld ); 31099 31100 return isSphereViewable( _sphere ); 31101 31102 } 31103 31104 function isSpriteViewable( sprite ) { 31105 31106 _sphere.center.set( 0, 0, 0 ); 31107 _sphere.radius = 0.7071067811865476; 31108 _sphere.applyMatrix4( sprite.matrixWorld ); 31109 31110 return isSphereViewable( _sphere ); 31111 31112 } 31113 31114 function isSphereViewable( sphere ) { 31115 31116 if ( ! _frustum.intersectsSphere( sphere ) ) return false;
31117 31118 var numPlanes = _clipping.numPlanes; 31119 31120 if ( numPlanes === 0 ) return true; 31121 31122 var planes = _this.clippingPlanes, 31123 31124 center = sphere.center, 31125 negRad = - sphere.radius, 31126 i = 0; 31127 31128 do { 31129 31130 // out when deeper than radius in the negative halfspace 31131 if ( planes[ i ].distanceToPoint( center ) < negRad ) return false; 31132 31133 } while ( ++ i !== numPlanes ); 31134 31135 return true; 31136 31137 } 31138 */ 31139 31140 function projectObject( object, camera, sortObjects ) { 31141 31142 if ( object.visible === false ) return; 31143 31144 var visible = object.layers.test( camera.layers ); 31145 31146 if ( visible ) { 31147 31148 if ( object.isLight ) { 31149 31150 currentRenderState.pushLight( object ); 31151 31152 if ( object.castShadow ) { 31153 31154 currentRenderState.pushShadow( object ); 31155 31156 } 31157 31158 } else if ( object.isSprite ) { 31159 31160 if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { 31161 31162 currentRenderState.pushSprite( object ); 31163 31164 } 31165 31166 } else if ( object.isImmediateRenderObject ) { 31167 31168 if ( sortObjects ) { 31169 31170 _vector3.setFromMatrixPosition( object.matrixWorld ) 31171 .applyMatrix4( _projScreenMatrix ); 31172 31173 } 31174 31175 currentRenderList.push( object, null, object.material, _vector3.z, null ); 31176 31177 } else if ( object.isMesh || object.isLine || object.isPoints ) { 31178 31179 if ( object.isSkinnedMesh ) { 31180 31181 object.skeleton.update(); 31182 31183 } 31184 31185 if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) { 31186 31187 if ( sortObjects ) { 31188 31189 _vector3.setFromMatrixPosition( object.matrixWorld ) 31190 .applyMatrix4( _projScreenMatrix ); 31191 31192 } 31193 31194 var geometry = objects.update( object ); 31195 var material = object.material; 31196 31197 if ( Array.isArray( material ) ) { 31198 31199 var groups = geometry.groups; 31200 31201 for ( var i = 0, l = groups.length; i < l; i ++ ) { 31202 31203 var group = groups[ i ]; 31204 var groupMaterial = material[ group.materialIndex ]; 31205 31206 if ( groupMaterial && groupMaterial.visible ) { 31207 31208 currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group ); 31209 31210 } 31211 31212 } 31213 31214 } else if ( material.visible ) { 31215 31216 currentRenderList.push( object, geometry, material, _vector3.z, null ); 31217 31218 } 31219 31220 } 31221 31222 } 31223 31224 } 31225 31226 var children = object.children; 31227 31228 for ( var i = 0, l = children.length; i < l; i ++ ) { 31229 31230 projectObject( children[ i ], camera, sortObjects ); 31231 31232 } 31233 31234 } 31235 31236 function renderObjects( renderList, scene, camera, overrideMaterial ) { 31237 31238 for ( var i = 0, l = renderList.length; i < l; i ++ ) { 31239 31240 var renderItem = renderList[ i ]; 31241 31242 var object = renderItem.object; 31243 var geometry = renderItem.geometry; 31244 var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial; 31245 var group = renderItem.group; 31246 31247 if ( camera.isArrayCamera ) { 31248 31249 _currentArrayCamera = camera; 31250 31251 var cameras = camera.cameras; 31252 31253 for ( var j = 0, jl = cameras.length; j < jl; j ++ ) { 31254 31255 var camera2 = cameras[ j ]; 31256 31257 if ( object.layers.test( camera2.layers ) ) { 31258 31259 if ( 'viewport' in camera2 ) { // XR 31260 31261 state.viewport( _currentViewport.copy( camera2.viewport ) ); 31262 31263 } else { 31264 31265 var bounds = camera2.bounds; 31266 31267 var x = bounds.x * _width; 31268 var y = bounds.y * _height; 31269 var width = bounds.z * _width; 31270 var height = bounds.w * _height; 31271 31272 state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) ); 31273 31274 } 31275 31276 renderObject( object, scene, camera2, geometry, material, group ); 31277 31278 } 31279 31280 } 31281 31282 } else { 31283 31284 _currentArrayCamera = null; 31285 31286 renderObject( object, scene, camera, geometry, material, group ); 31287 31288 } 31289 31290 } 31291 31292 } 31293 31294 function renderObject( object, scene, camera, geometry, material, group ) { 31295 31296 object.onBeforeRender( _this, scene, camera, geometry, material, group ); 31297 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); 31298 31299 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); 31300 object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); 31301 31302 if ( object.isImmediateRenderObject ) { 31303 31304 var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 ); 31305 31306 state.setMaterial( material, frontFaceCW ); 31307 31308 var program = setProgram( camera, scene.fog, material, object ); 31309 31310 _currentGeometryProgram = ''; 31311
31312 renderObjectImmediate( object, program, material ); 31313 31314 } else { 31315 31316 _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); 31317 31318 } 31319 31320 object.onAfterRender( _this, scene, camera, geometry, material, group ); 31321 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); 31322 31323 } 31324 31325 function initMaterial( material, fog, object ) { 31326 31327 var materialProperties = properties.get( material ); 31328 31329 var lights = currentRenderState.state.lights; 31330 var shadowsArray = currentRenderState.state.shadowsArray; 31331 31332 var parameters = programCache.getParameters( 31333 material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); 31334 31335 var code = programCache.getProgramCode( material, parameters ); 31336 31337 var program = materialProperties.program; 31338 var programChange = true; 31339 31340 if ( program === undefined ) { 31341 31342 // new material 31343 material.addEventListener( 'dispose', onMaterialDispose ); 31344 31345 } else if ( program.code !== code ) { 31346 31347 // changed glsl or parameters 31348 releaseMaterialProgramReference( material ); 31349 31350 } else if ( materialProperties.lightsHash !== lights.state.hash ) { 31351 31352 properties.update( material, 'lightsHash', lights.state.hash ); 31353 programChange = false; 31354 31355 } else if ( parameters.shaderID !== undefined ) { 31356 31357 // same glsl and uniform list 31358 return; 31359 31360 } else { 31361 31362 // only rebuild uniform list 31363 programChange = false; 31364 31365 } 31366 31367 if ( programChange ) { 31368 31369 if ( parameters.shaderID ) { 31370 31371 var shader = ShaderLib[ parameters.shaderID ]; 31372 31373 materialProperties.shader = { 31374 name: material.type, 31375 uniforms: UniformsUtils.clone( shader.uniforms ), 31376 vertexShader: shader.vertexShader, 31377 fragmentShader: shader.fragmentShader 31378 }; 31379 31380 } else { 31381 31382 materialProperties.shader = { 31383 name: material.type, 31384 uniforms: material.uniforms, 31385 vertexShader: material.vertexShader, 31386 fragmentShader: material.fragmentShader 31387 }; 31388 31389 } 31390 31391 material.onBeforeCompile( materialProperties.shader, _this ); 31392 31393 program = programCache.acquireProgram( material, materialProperties.shader, parameters, code ); 31394 31395 materialProperties.program = program; 31396 material.program = program; 31397 31398 } 31399 31400 var programAttributes = program.getAttributes(); 31401 31402 if ( material.morphTargets ) { 31403 31404 material.numSupportedMorphTargets = 0; 31405 31406 for ( var i = 0; i < _this.maxMorphTargets; i ++ ) { 31407 31408 if ( programAttributes[ 'morphTarget' + i ] >= 0 ) { 31409 31410 material.numSupportedMorphTargets ++; 31411 31412 } 31413 31414 } 31415 31416 } 31417 31418 if ( material.morphNormals ) { 31419 31420 material.numSupportedMorphNormals = 0; 31421 31422 for ( var i = 0; i < _this.maxMorphNormals; i ++ ) { 31423 31424 if ( programAttributes[ 'morphNormal' + i ] >= 0 ) { 31425 31426 material.numSupportedMorphNormals ++; 31427 31428 } 31429 31430 } 31431 31432 } 31433 31434 var uniforms = materialProperties.shader.uniforms; 31435 31436 if ( ! material.isShaderMaterial && 31437 ! material.isRawShaderMaterial || 31438 material.clipping === true ) { 31439 31440 materialProperties.numClippingPlanes = _clipping.numPlanes; 31441 materialProperties.numIntersection = _clipping.numIntersection; 31442 uniforms.clippingPlanes = _clipping.uniform; 31443 31444 } 31445 31446 materialProperties.fog = fog; 31447 31448 // store the light setup it was created for 31449 31450 materialProperties.lightsHash = lights.state.hash; 31451 31452 if ( material.lights ) { 31453 31454 // wire up the material to this renderer's lighting state 31455 31456 uniforms.ambientLightColor.value = lights.state.ambient; 31457 uniforms.directionalLights.value = lights.state.directional; 31458 uniforms.spotLights.value = lights.state.spot; 31459 uniforms.rectAreaLights.value = lights.state.rectArea; 31460 uniforms.pointLights.value = lights.state.point; 31461 uniforms.hemisphereLights.value = lights.state.hemi; 31462 31463 uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; 31464 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; 31465 uniforms.spotShadowMap.value = lights.state.spotShadowMap; 31466 uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; 31467 uniforms.pointShadowMap.value = lights.state.pointShadowMap; 31468 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; 31469 // TODO (abelnation): add area lights shadow info to uniforms 31470 31471 } 31472 31473 var progUniforms = materialProperties.program.getUniforms(), 31474 uniformsList = 31475 WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); 31476 31477 materialProperties.uniformsList = uniformsList; 31478 31479 } 31480 31481 function setProgram( camera, fog, material, object ) { 31482 31483 _usedTextureUnits = 0; 31484 31485 var materialProperties = properties.get( material ); 31486 var lights = currentRenderState.state.lights; 31487
31488 if ( _clippingEnabled ) { 31489 31490 if ( _localClippingEnabled || camera !== _currentCamera ) { 31491 31492 var useCache = 31493 camera === _currentCamera && 31494 material.id === _currentMaterialId; 31495 31496 // we might want to call this function with some ClippingGroup 31497 // object instead of the material, once it becomes feasible 31498 // (#8465, #8379) 31499 _clipping.setState( 31500 material.clippingPlanes, material.clipIntersection, material.clipShadows, 31501 camera, materialProperties, useCache ); 31502 31503 } 31504 31505 } 31506 31507 if ( material.needsUpdate === false ) { 31508 31509 if ( materialProperties.program === undefined ) { 31510 31511 material.needsUpdate = true; 31512 31513 } else if ( material.fog && materialProperties.fog !== fog ) { 31514 31515 material.needsUpdate = true; 31516 31517 } else if ( material.lights && materialProperties.lightsHash !== lights.state.hash ) { 31518 31519 material.needsUpdate = true; 31520 31521 } else if ( materialProperties.numClippingPlanes !== undefined && 31522 ( materialProperties.numClippingPlanes !== _clipping.numPlanes || 31523 materialProperties.numIntersection !== _clipping.numIntersection ) ) { 31524 31525 material.needsUpdate = true; 31526 31527 } 31528 31529 } 31530 31531 if ( material.needsUpdate ) { 31532 31533 initMaterial( material, fog, object ); 31534 material.needsUpdate = false; 31535 31536 } 31537 31538 var refreshProgram = false; 31539 var refreshMaterial = false; 31540 var refreshLights = false; 31541 31542 var program = materialProperties.program, 31543 p_uniforms = program.getUniforms(), 31544 m_uniforms = materialProperties.shader.uniforms; 31545 31546 if ( state.useProgram( program.program ) ) { 31547 31548 refreshProgram = true; 31549 refreshMaterial = true; 31550 refreshLights = true; 31551 31552 } 31553 31554 if ( material.id !== _currentMaterialId ) { 31555 31556 _currentMaterialId = material.id; 31557 31558 refreshMaterial = true; 31559 31560 } 31561 31562 if ( refreshProgram || camera !== _currentCamera ) { 31563 31564 p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix ); 31565 31566 if ( capabilities.logarithmicDepthBuffer ) { 31567 31568 p_uniforms.setValue( _gl, 'logDepthBufFC', 31569 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); 31570 31571 } 31572 31573 // Avoid unneeded uniform updates per ArrayCamera's sub-camera 31574 31575 if ( _currentCamera !== ( _currentArrayCamera || camera ) ) { 31576 31577 _currentCamera = ( _currentArrayCamera || camera ); 31578 31579 // lighting uniforms depend on the camera so enforce an update 31580 // now, in case this material supports lights - or later, when 31581 // the next material that does gets activated: 31582 31583 refreshMaterial = true; // set to true on material change 31584 refreshLights = true; // remains set until update done 31585 31586 } 31587 31588 // load material specific uniforms 31589 // (shader material also gets them for the sake of genericity) 31590 31591 if ( material.isShaderMaterial || 31592 material.isMeshPhongMaterial || 31593 material.isMeshStandardMaterial || 31594 material.envMap ) { 31595 31596 var uCamPos = p_uniforms.map.cameraPosition; 31597 31598 if ( uCamPos !== undefined ) { 31599 31600 uCamPos.setValue( _gl, 31601 _vector3.setFromMatrixPosition( camera.matrixWorld ) ); 31602 31603 } 31604 31605 } 31606 31607 if ( material.isMeshPhongMaterial || 31608 material.isMeshLambertMaterial || 31609 material.isMeshBasicMaterial || 31610 material.isMeshStandardMaterial || 31611 material.isShaderMaterial || 31612 material.skinning ) { 31613 31614 p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); 31615 31616 } 31617 31618 } 31619 31620 // skinning uniforms must be set even if material didn't change 31621 // auto-setting of texture unit for bone texture must go before other textures 31622 // not sure why, but otherwise weird things happen 31623 31624 if ( material.skinning ) { 31625 31626 p_uniforms.setOptional( _gl, object, 'bindMatrix' ); 31627 p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' ); 31628 31629 var skeleton = object.skeleton; 31630 31631 if ( skeleton ) { 31632 31633 var bones = skeleton.bones; 31634 31635 if ( capabilities.floatVertexTextures ) { 31636 31637 if ( skeleton.boneTexture === undefined ) { 31638 31639 // layout (1 matrix = 4 pixels) 31640 // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) 31641 // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) 31642 // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) 31643 // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) 31644 // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) 31645 31646 31647 var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
vendor: 4,185 bytes, lines 31648-31801
31648 size = _Math.ceilPowerOfTwo( size ); 31649 size = Math.max( size, 4 ); 31650 31651 var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel 31652 boneMatrices.set( skeleton.boneMatrices ); // copy current values 31653 31654 var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); 31655 boneTexture.needsUpdate = true; 31656 31657 skeleton.boneMatrices = boneMatrices; 31658 skeleton.boneTexture = boneTexture; 31659 skeleton.boneTextureSize = size; 31660 31661 } 31662 31663 p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture ); 31664 p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); 31665 31666 } else { 31667 31668 p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' ); 31669 31670 } 31671 31672 } 31673 31674 } 31675 31676 if ( refreshMaterial ) { 31677 31678 p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); 31679 p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); 31680 31681 if ( material.lights ) { 31682 31683 // the current material requires lighting info 31684 31685 // note: all lighting uniforms are always set correctly 31686 // they simply reference the renderer's state for their 31687 // values 31688 // 31689 // use the current material's .needsUpdate flags to set 31690 // the GL state when required 31691 31692 markUniformsLightsNeedsUpdate( m_uniforms, refreshLights ); 31693 31694 } 31695 31696 // refresh uniforms common to several materials 31697 31698 if ( fog && material.fog ) { 31699 31700 refreshUniformsFog( m_uniforms, fog ); 31701 31702 } 31703 31704 if ( material.isMeshBasicMaterial ) { 31705 31706 refreshUniformsCommon( m_uniforms, material ); 31707 31708 } else if ( material.isMeshLambertMaterial ) { 31709 31710 refreshUniformsCommon( m_uniforms, material ); 31711 refreshUniformsLambert( m_uniforms, material ); 31712 31713 } else if ( material.isMeshPhongMaterial ) { 31714 31715 refreshUniformsCommon( m_uniforms, material ); 31716 31717 if ( material.isMeshToonMaterial ) { 31718 31719 refreshUniformsToon( m_uniforms, material ); 31720 31721 } else { 31722 31723 refreshUniformsPhong( m_uniforms, material ); 31724 31725 } 31726 31727 } else if ( material.isMeshStandardMaterial ) { 31728 31729 refreshUniformsCommon( m_uniforms, material ); 31730 31731 if ( material.isMeshPhysicalMaterial ) { 31732 31733 refreshUniformsPhysical( m_uniforms, material ); 31734 31735 } else { 31736 31737 refreshUniformsStandard( m_uniforms, material ); 31738 31739 } 31740 31741 } else if ( material.isMeshDepthMaterial ) { 31742 31743 refreshUniformsCommon( m_uniforms, material ); 31744 refreshUniformsDepth( m_uniforms, material ); 31745 31746 } else if ( material.isMeshDistanceMaterial ) { 31747 31748 refreshUniformsCommon( m_uniforms, material ); 31749 refreshUniformsDistance( m_uniforms, material ); 31750 31751 } else if ( material.isMeshNormalMaterial ) { 31752 31753 refreshUniformsCommon( m_uniforms, material ); 31754 refreshUniformsNormal( m_uniforms, material ); 31755 31756 } else if ( material.isLineBasicMaterial ) { 31757 31758 refreshUniformsLine( m_uniforms, material ); 31759 31760 if ( material.isLineDashedMaterial ) { 31761 31762 refreshUniformsDash( m_uniforms, material ); 31763 31764 } 31765 31766 } else if ( material.isPointsMaterial ) { 31767 31768 refreshUniformsPoints( m_uniforms, material ); 31769 31770 } else if ( material.isShadowMaterial ) { 31771 31772 m_uniforms.color.value = material.color; 31773 m_uniforms.opacity.value = material.opacity; 31774 31775 } 31776 31777 // RectAreaLight Texture 31778 // TODO (mrdoob): Find a nicer implementation 31779 31780 if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1; 31781 if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2; 31782 31783 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); 31784 31785 } 31786 31787 if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { 31788 31789 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); 31790 material.uniformsNeedUpdate = false; 31791 31792 } 31793 31794 // common matrices 31795 31796 p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); 31797 p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); 31798 p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); 31799 31800 return program; 31801
31802 } 31803 31804 // Uniforms (refresh uniforms objects) 31805 31806 function refreshUniformsCommon( uniforms, material ) { 31807 31808 uniforms.opacity.value = material.opacity; 31809 31810 if ( material.color ) { 31811 31812 uniforms.diffuse.value = material.color; 31813 31814 } 31815 31816 if ( material.emissive ) { 31817 31818 uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); 31819 31820 } 31821 31822 if ( material.map ) { 31823 31824 uniforms.map.value = material.map; 31825 31826 } 31827 31828 if ( material.alphaMap ) { 31829 31830 uniforms.alphaMap.value = material.alphaMap; 31831 31832 } 31833 31834 if ( material.specularMap ) { 31835 31836 uniforms.specularMap.value = material.specularMap; 31837 31838 } 31839 31840 if ( material.envMap ) { 31841 31842 uniforms.envMap.value = material.envMap; 31843 31844 // don't flip CubeTexture envMaps, flip everything else: 31845 // WebGLRenderTargetCube will be flipped for backwards compatibility 31846 // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture 31847 // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future 31848 uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1; 31849 31850 uniforms.reflectivity.value = material.reflectivity; 31851 uniforms.refractionRatio.value = material.refractionRatio; 31852 31853 uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel; 31854 31855 } 31856 31857 if ( material.lightMap ) { 31858 31859 uniforms.lightMap.value = material.lightMap; 31860 uniforms.lightMapIntensity.value = material.lightMapIntensity; 31861 31862 } 31863 31864 if ( material.aoMap ) { 31865 31866 uniforms.aoMap.value = material.aoMap; 31867 uniforms.aoMapIntensity.value = material.aoMapIntensity; 31868 31869 } 31870 31871 // uv repeat and offset setting priorities 31872 // 1. color map 31873 // 2. specular map 31874 // 3. normal map 31875 // 4. bump map 31876 // 5. alpha map 31877 // 6. emissive map 31878 31879 var uvScaleMap; 31880 31881 if ( material.map ) { 31882 31883 uvScaleMap = material.map; 31884 31885 } else if ( material.specularMap ) { 31886 31887 uvScaleMap = material.specularMap; 31888 31889 } else if ( material.displacementMap ) { 31890 31891 uvScaleMap = material.displacementMap; 31892 31893 } else if ( material.normalMap ) { 31894 31895 uvScaleMap = material.normalMap; 31896 31897 } else if ( material.bumpMap ) { 31898 31899 uvScaleMap = material.bumpMap; 31900 31901 } else if ( material.roughnessMap ) { 31902 31903 uvScaleMap = material.roughnessMap; 31904 31905 } else if ( material.metalnessMap ) { 31906 31907 uvScaleMap = material.metalnessMap; 31908 31909 } else if ( material.alphaMap ) { 31910 31911 uvScaleMap = material.alphaMap; 31912 31913 } else if ( material.emissiveMap ) { 31914 31915 uvScaleMap = material.emissiveMap; 31916 31917 } 31918 31919 if ( uvScaleMap !== undefined ) { 31920 31921 // backwards compatibility 31922 if ( uvScaleMap.isWebGLRenderTarget ) { 31923 31924 uvScaleMap = uvScaleMap.texture; 31925 31926 } 31927 31928 if ( uvScaleMap.matrixAutoUpdate === true ) { 31929 31930 uvScaleMap.updateMatrix(); 31931 31932 } 31933 31934 uniforms.uvTransform.value.copy( uvScaleMap.matrix ); 31935 31936 } 31937 31938 } 31939 31940 function refreshUniformsLine( uniforms, material ) { 31941 31942 uniforms.diffuse.value = material.color; 31943 uniforms.opacity.value = material.opacity; 31944 31945 } 31946 31947 function refreshUniformsDash( uniforms, material ) { 31948 31949 uniforms.dashSize.value = material.dashSize; 31950 uniforms.totalSize.value = material.dashSize + material.gapSize; 31951 uniforms.scale.value = material.scale; 31952 31953 } 31954 31955 function refreshUniformsPoints( uniforms, material ) { 31956 31957 uniforms.diffuse.value = material.color; 31958 uniforms.opacity.value = material.opacity; 31959 uniforms.size.value = material.size * _pixelRatio; 31960 uniforms.scale.value = _height * 0.5; 31961 31962 uniforms.map.value = material.map; 31963 31964 if ( material.map !== null ) { 31965 31966 if ( material.map.matrixAutoUpdate === true ) { 31967 31968 material.map.updateMatrix(); 31969 31970 } 31971 31972 uniforms.uvTransform.value.copy( material.map.matrix ); 31973 31974 } 31975 31976 } 31977 31978 function refreshUniformsFog( uniforms, fog ) { 31979 31980 uniforms.fogColor.value = fog.color; 31981 31982 if ( fog.isFog ) { 31983 31984 uniforms.fogNear.value = fog.near; 31985 uniforms.fogFar.value = fog.far; 31986 31987 } else if ( fog.isFogExp2 ) { 31988 31989 uniforms.fogDensity.value = fog.density; 31990 31991 } 31992 31993 } 31994 31995 function refreshUniformsLambert( uniforms, material ) { 31996 31997 if ( material.emissiveMap ) { 31998 31999 uniforms.emissiveMap.value = material.emissiveMap; 32000 32001 } 32002 32003 } 32004 32005 function refreshUniformsPhong( uniforms, material ) { 32006 32007 uniforms.specular.value = material.specular; 32008 uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) 32009 32010 if ( material.emissiveMap ) { 32011 32012 uniforms.emissiveMap.value = material.emissiveMap; 32013 32014 } 32015 32016 if ( material.bumpMap ) { 32017 32018 uniforms.bumpMap.value = material.bumpMap; 32019 uniforms.bumpScale.value = material.bumpScale; 32020 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 32021 32022 } 32023 32024 if ( material.normalMap ) { 32025 32026 uniforms.normalMap.value = material.normalMap; 32027 uniforms.normalScale.value.copy( material.normalScale ); 32028 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 32029 32030 } 32031 32032 if ( material.displacementMap ) { 32033 32034 uniforms.displacementMap.value = material.displacementMap; 32035 uniforms.displacementScale.value = material.displacementScale; 32036 uniforms.displacementBias.value = material.displacementBias; 32037 32038 } 32039 32040 } 32041 32042 function refreshUniformsToon( uniforms, material ) { 32043 32044 refreshUniformsPhong( uniforms, material ); 32045 32046 if ( material.gradientMap ) { 32047 32048 uniforms.gradientMap.value = material.gradientMap; 32049 32050 } 32051 32052 } 32053 32054 function refreshUniformsStandard( uniforms, material ) { 32055 32056 uniforms.roughness.value = material.roughness; 32057 uniforms.metalness.value = material.metalness; 32058 32059 if ( material.roughnessMap ) { 32060 32061 uniforms.roughnessMap.value = material.roughnessMap; 32062 32063 } 32064 32065 if ( material.metalnessMap ) { 32066 32067 uniforms.metalnessMap.value = material.metalnessMap; 32068 32069 } 32070 32071 if ( material.emissiveMap ) { 32072 32073 uniforms.emissiveMap.value = material.emissiveMap; 32074 32075 } 32076 32077 if ( material.bumpMap ) { 32078 32079 uniforms.bumpMap.value = material.bumpMap; 32080 uniforms.bumpScale.value = material.bumpScale; 32081 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 32082 32083 } 32084 32085 if ( material.normalMap ) { 32086 32087 uniforms.normalMap.value = material.normalMap; 32088 uniforms.normalScale.value.copy( material.normalScale ); 32089 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 32090 32091 } 32092 32093 if ( material.displacementMap ) { 32094 32095 uniforms.displacementMap.value = material.displacementMap; 32096 uniforms.displacementScale.value = material.displacementScale; 32097 uniforms.displacementBias.value = material.displacementBias; 32098 32099 } 32100 32101 if ( material.envMap ) { 32102 32103 //uniforms.envMap.value = material.envMap; // part of uniforms common 32104 uniforms.envMapIntensity.value = material.envMapIntensity; 32105 32106 } 32107 32108 } 32109 32110 function refreshUniformsPhysical( uniforms, material ) { 32111 32112 uniforms.clearCoat.value = material.clearCoat; 32113 uniforms.clearCoatRoughness.value = material.clearCoatRoughness; 32114 32115 refreshUniformsStandard( uniforms, material ); 32116 32117 } 32118 32119 function refreshUniformsDepth( uniforms, material ) { 32120 32121 if ( material.displacementMap ) { 32122 32123 uniforms.displacementMap.value = material.displacementMap; 32124 uniforms.displacementScale.value = material.displacementScale; 32125 uniforms.displacementBias.value = material.displacementBias; 32126 32127 } 32128 32129 } 32130 32131 function refreshUniformsDistance( uniforms, material ) { 32132 32133 if ( material.displacementMap ) { 32134 32135 uniforms.displacementMap.value = material.displacementMap; 32136 uniforms.displacementScale.value = material.displacementScale; 32137 uniforms.displacementBias.value = material.displacementBias; 32138 32139 } 32140 32141 uniforms.referencePosition.value.copy( material.referencePosition ); 32142 uniforms.nearDistance.value = material.nearDistance; 32143 uniforms.farDistance.value = material.farDistance; 32144
32145 } 32146 32147 function refreshUniformsNormal( uniforms, material ) { 32148 32149 if ( material.bumpMap ) { 32150 32151 uniforms.bumpMap.value = material.bumpMap; 32152 uniforms.bumpScale.value = material.bumpScale; 32153 if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; 32154 32155 } 32156 32157 if ( material.normalMap ) { 32158 32159 uniforms.normalMap.value = material.normalMap; 32160 uniforms.normalScale.value.copy( material.normalScale ); 32161 if ( material.side === BackSide ) uniforms.normalScale.value.negate(); 32162 32163 } 32164 32165 if ( material.displacementMap ) { 32166 32167 uniforms.displacementMap.value = material.displacementMap; 32168 uniforms.displacementScale.value = material.displacementScale; 32169 uniforms.displacementBias.value = material.displacementBias; 32170 32171 } 32172 32173 } 32174 32175 // If uniforms are marked as clean, they don't need to be loaded to the GPU. 32176 32177 function markUniformsLightsNeedsUpdate( uniforms, value ) { 32178 32179 uniforms.ambientLightColor.needsUpdate = value; 32180 32181 uniforms.directionalLights.needsUpdate = value; 32182 uniforms.pointLights.needsUpdate = value; 32183 uniforms.spotLights.needsUpdate = value; 32184 uniforms.rectAreaLights.needsUpdate = value; 32185 uniforms.hemisphereLights.needsUpdate = value; 32186 32187 } 32188 32189 // Textures 32190 32191 function allocTextureUnit() { 32192 32193 var textureUnit = _usedTextureUnits; 32194 32195 if ( textureUnit >= capabilities.maxTextures ) { 32196 32197 console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); 32198 32199 } 32200 32201 _usedTextureUnits += 1; 32202 32203 return textureUnit; 32204 32205 } 32206 32207 this.allocTextureUnit = allocTextureUnit; 32208 32209 // this.setTexture2D = setTexture2D; 32210 this.setTexture2D = ( function () { 32211 32212 var warned = false; 32213 32214 // backwards compatibility: peel texture.texture 32215 return function setTexture2D( texture, slot ) { 32216 32217 if ( texture && texture.isWebGLRenderTarget ) { 32218 32219 if ( ! warned ) { 32220 32221 console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." ); 32222 warned = true; 32223 32224 } 32225 32226 texture = texture.texture; 32227 32228 } 32229 32230 textures.setTexture2D( texture, slot ); 32231 32232 }; 32233 32234 }() ); 32235 32236 this.setTexture = ( function () { 32237 32238 var warned = false; 32239 32240 return function setTexture( texture, slot ) { 32241 32242 if ( ! warned ) { 32243 32244 console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." ); 32245 warned = true; 32246 32247 } 32248 32249 textures.setTexture2D( texture, slot ); 32250 32251 }; 32252 32253 }() ); 32254 32255 this.setTextureCube = ( function () { 32256 32257 var warned = false; 32258 32259 return function setTextureCube( texture, slot ) { 32260 32261 // backwards compatibility: peel texture.texture 32262 if ( texture && texture.isWebGLRenderTargetCube ) { 32263 32264 if ( ! warned ) { 32265 32266 console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." ); 32267 warned = true; 32268 32269 } 32270 32271 texture = texture.texture; 32272 32273 } 32274 32275 // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture 32276 // TODO: unify these code paths 32277 if ( ( texture && texture.isCubeTexture ) || 32278 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { 32279 32280 // CompressedTexture can have Array in image :/ 32281 32282 // this function alone should take care of cube textures 32283 textures.setTextureCube( texture, slot ); 32284 32285 } else { 32286 32287 // assumed: texture property of THREE.WebGLRenderTargetCube 32288 32289 textures.setTextureCubeDynamic( texture, slot ); 32290 32291 } 32292 32293 }; 32294 32295 }() ); 32296 32297 // 32298 32299 this.setFramebuffer = function ( value ) { 32300 32301 _framebuffer = value; 32302 32303 }; 32304 32305 this.getRenderTarget = function () { 32306 32307 return _currentRenderTarget; 32308 32309 }; 32310 32311 this.setRenderTarget = function ( renderTarget ) { 32312 32313 _currentRenderTarget = renderTarget; 32314 32315 if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { 32316 32317 textures.setupRenderTarget( renderTarget ); 32318 32319 } 32320 32321 var framebuffer = _framebuffer; 32322 var isCube = false;
32323 32324 if ( renderTarget ) { 32325 32326 var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; 32327 32328 if ( renderTarget.isWebGLRenderTargetCube ) { 32329 32330 framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ]; 32331 isCube = true; 32332 32333 } else { 32334 32335 framebuffer = __webglFramebuffer; 32336 32337 } 32338 32339 _currentViewport.copy( renderTarget.viewport ); 32340 _currentScissor.copy( renderTarget.scissor ); 32341 _currentScissorTest = renderTarget.scissorTest; 32342 32343 } else { 32344 32345 _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ); 32346 _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ); 32347 _currentScissorTest = _scissorTest; 32348 32349 } 32350 32351 if ( _currentFramebuffer !== framebuffer ) { 32352 32353 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); 32354 _currentFramebuffer = framebuffer; 32355 32356 } 32357 32358 state.viewport( _currentViewport ); 32359 state.scissor( _currentScissor ); 32360 state.setScissorTest( _currentScissorTest ); 32361 32362 if ( isCube ) { 32363 32364 var textureProperties = properties.get( renderTarget.texture ); 32365 _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel ); 32366 32367 } 32368 32369 }; 32370 32371 this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) { 32372 32373 if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { 32374 32375 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); 32376 return; 32377 32378 } 32379 32380 var framebuffer = properties.get( renderTarget ).__webglFramebuffer; 32381 32382 if ( framebuffer ) { 32383 32384 var restore = false; 32385 32386 if ( framebuffer !== _currentFramebuffer ) { 32387 32388 _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); 32389 32390 restore = true; 32391 32392 } 32393 32394 try { 32395 32396 var texture = renderTarget.texture; 32397 var textureFormat = texture.format; 32398 var textureType = texture.type; 32399 32400 if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { 32401 32402 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' ); 32403 return; 32404 32405 } 32406 32407 if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513) 32408 ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox 32409 ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) { 32410 32411 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' ); 32412 return; 32413 32414 } 32415 32416 if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { 32417 32418 // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) 32419 32420 if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) { 32421 32422 _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer ); 32423 32424 } 32425 32426 } else { 32427 32428 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); 32429 32430 } 32431 32432 } finally { 32433 32434 if ( restore ) { 32435 32436 _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); 32437 32438 } 32439 32440 } 32441 32442 } 32443 32444 }; 32445 32446 this.copyFramebufferToTexture = function ( position, texture, level ) { 32447 32448 var width = texture.image.width; 32449 var height = texture.image.height; 32450 var glFormat = utils.convert( texture.format ); 32451 32452 this.setTexture2D( texture, 0 ); 32453 32454 _gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, glFormat, position.x, position.y, width, height, 0 ); 32455 32456 }; 32457 32458 this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) { 32459 32460 var width = srcTexture.image.width; 32461 var height = srcTexture.image.height; 32462 var glFormat = utils.convert( dstTexture.format ); 32463 var glType = utils.convert( dstTexture.type ); 32464 32465 this.setTexture2D( dstTexture, 0 ); 32466 32467 if ( srcTexture.isDataTexture ) { 32468 32469 _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data ); 32470 32471 } else { 32472
32473 _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, glFormat, glType, srcTexture.image ); 32474 32475 } 32476 32477 }; 32478 32479 } 32480 32481 /** 32482 * @author mrdoob / http://mrdoob.com/ 32483 * @author alteredq / http://alteredqualia.com/ 32484 */ 32485 32486 function FogExp2( color, density ) { 32487 32488 this.name = ''; 32489 32490 this.color = new Color( color ); 32491 this.density = ( density !== undefined ) ? density : 0.00025; 32492 32493 } 32494 32495 FogExp2.prototype.isFogExp2 = true; 32496 32497 FogExp2.prototype.clone = function () { 32498 32499 return new FogExp2( this.color, this.density ); 32500 32501 }; 32502 32503 FogExp2.prototype.toJSON = function ( /* meta */ ) { 32504 32505 return { 32506 type: 'FogExp2', 32507 color: this.color.getHex(), 32508 density: this.density 32509 }; 32510 32511 }; 32512 32513 /** 32514 * @author mrdoob / http://mrdoob.com/ 32515 * @author alteredq / http://alteredqualia.com/ 32516 */ 32517 32518 function Fog( color, near, far ) { 32519 32520 this.name = ''; 32521 32522 this.color = new Color( color ); 32523 32524 this.near = ( near !== undefined ) ? near : 1; 32525 this.far = ( far !== undefined ) ? far : 1000; 32526 32527 } 32528 32529 Fog.prototype.isFog = true; 32530 32531 Fog.prototype.clone = function () { 32532 32533 return new Fog( this.color, this.near, this.far ); 32534 32535 }; 32536 32537 Fog.prototype.toJSON = function ( /* meta */ ) { 32538 32539 return { 32540 type: 'Fog', 32541 color: this.color.getHex(), 32542 near: this.near, 32543 far: this.far 32544 }; 32545 32546 }; 32547 32548 /** 32549 * @author mrdoob / http://mrdoob.com/ 32550 */ 32551 32552 function Scene() { 32553 32554 Object3D.call( this ); 32555 32556 this.type = 'Scene'; 32557 32558 this.background = null; 32559 this.fog = null; 32560 this.overrideMaterial = null; 32561 32562 this.autoUpdate = true; // checked by the renderer 32563 32564 } 32565 32566 Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { 32567 32568 constructor: Scene, 32569 32570 copy: function ( source, recursive ) { 32571 32572 Object3D.prototype.copy.call( this, source, recursive ); 32573 32574 if ( source.background !== null ) this.background = source.background.clone(); 32575 if ( source.fog !== null ) this.fog = source.fog.clone(); 32576 if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); 32577 32578 this.autoUpdate = source.autoUpdate; 32579 this.matrixAutoUpdate = source.matrixAutoUpdate; 32580 32581 return this; 32582 32583 }, 32584 32585 toJSON: function ( meta ) { 32586 32587 var data = Object3D.prototype.toJSON.call( this, meta ); 32588 32589 if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); 32590 if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); 32591 32592 return data; 32593 32594 } 32595 32596 } ); 32597 32598 /** 32599 * @author alteredq / http://alteredqualia.com/ 32600 * 32601 * parameters = { 32602 * color: <hex>, 32603 * opacity: <float>, 32604 * map: new THREE.Texture( <Image> ), 32605 * 32606 * uvOffset: new THREE.Vector2(), 32607 * uvScale: new THREE.Vector2() 32608 * } 32609 */ 32610 32611 function SpriteMaterial( parameters ) { 32612 32613 Material.call( this ); 32614 32615 this.type = 'SpriteMaterial'; 32616 32617 this.color = new Color( 0xffffff ); 32618 this.map = null; 32619 32620 this.rotation = 0; 32621 32622 this.fog = false; 32623 this.lights = false; 32624 32625 this.setValues( parameters ); 32626 32627 } 32628 32629 SpriteMaterial.prototype = Object.create( Material.prototype ); 32630 SpriteMaterial.prototype.constructor = SpriteMaterial; 32631 SpriteMaterial.prototype.isSpriteMaterial = true; 32632 32633 SpriteMaterial.prototype.copy = function ( source ) { 32634 32635 Material.prototype.copy.call( this, source ); 32636 32637 this.color.copy( source.color ); 32638 this.map = source.map; 32639 32640 this.rotation = source.rotation; 32641 32642 return this; 32643 32644 }; 32645 32646 /** 32647 * @author mikael emtinger / http://gomo.se/ 32648 * @author alteredq / http://alteredqualia.com/ 32649 */ 32650 32651 function Sprite( material ) { 32652 32653 Object3D.call( this ); 32654 32655 this.type = 'Sprite'; 32656 32657 this.material = ( material !== undefined ) ? material : new SpriteMaterial(); 32658 32659 this.center = new Vector2( 0.5, 0.5 ); 32660 32661 } 32662 32663 Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), { 32664 32665 constructor: Sprite, 32666 32667 isSprite: true, 32668 32669 raycast: ( function () { 32670 32671 var intersectPoint = new Vector3(); 32672 var worldPosition = new Vector3(); 32673 var worldScale = new Vector3(); 32674 32675 return function raycast( raycaster, intersects ) { 32676 32677 worldPosition.setFromMatrixPosition( this.matrixWorld ); 32678 raycaster.ray.closestPointToPoint( worldPosition, intersectPoint ); 32679 32680 worldScale.setFromMatrixScale( this.matrixWorld ); 32681 var guessSizeSq = worldScale.x * worldScale.y / 4; 32682 32683 if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return; 32684 32685 var distance = raycaster.ray.origin.distanceTo( intersectPoint ); 32686 32687 if ( distance < raycaster.near || distance > raycaster.far ) return; 32688 32689 intersects.push( { 32690 32691 distance: distance, 32692 point: intersectPoint.clone(), 32693 face: null, 32694 object: this 32695 32696 } ); 32697 32698 }; 32699 32700 }() ), 32701 32702 clone: function () { 32703 32704 return new this.constructor( this.material ).copy( this ); 32705 32706 }, 32707
32708 copy: function ( source ) { 32709 32710 Object3D.prototype.copy.call( this, source ); 32711 32712 if ( source.center !== undefined ) this.center.copy( source.center ); 32713 32714 return this; 32715 32716 } 32717 32718 32719 } ); 32720 32721 /** 32722 * @author mikael emtinger / http://gomo.se/ 32723 * @author alteredq / http://alteredqualia.com/ 32724 * @author mrdoob / http://mrdoob.com/ 32725 */ 32726 32727 function LOD() { 32728 32729 Object3D.call( this ); 32730 32731 this.type = 'LOD'; 32732 32733 Object.defineProperties( this, { 32734 levels: { 32735 enumerable: true, 32736 value: [] 32737 } 32738 } ); 32739 32740 } 32741 32742 LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { 32743 32744 constructor: LOD, 32745 32746 copy: function ( source ) { 32747 32748 Object3D.prototype.copy.call( this, source, false ); 32749 32750 var levels = source.levels; 32751 32752 for ( var i = 0, l = levels.length; i < l; i ++ ) { 32753 32754 var level = levels[ i ]; 32755 32756 this.addLevel( level.object.clone(), level.distance ); 32757 32758 } 32759 32760 return this; 32761 32762 }, 32763 32764 addLevel: function ( object, distance ) { 32765 32766 if ( distance === undefined ) distance = 0; 32767 32768 distance = Math.abs( distance ); 32769 32770 var levels = this.levels; 32771 32772 for ( var l = 0; l < levels.length; l ++ ) { 32773 32774 if ( distance < levels[ l ].distance ) { 32775 32776 break; 32777 32778 } 32779 32780 } 32781 32782 levels.splice( l, 0, { distance: distance, object: object } ); 32783 32784 this.add( object ); 32785 32786 }, 32787 32788 getObjectForDistance: function ( distance ) { 32789 32790 var levels = this.levels; 32791 32792 for ( var i = 1, l = levels.length; i < l; i ++ ) { 32793 32794 if ( distance < levels[ i ].distance ) { 32795 32796 break; 32797 32798 } 32799 32800 } 32801 32802 return levels[ i - 1 ].object; 32803 32804 }, 32805 32806 raycast: ( function () { 32807 32808 var matrixPosition = new Vector3(); 32809 32810 return function raycast( raycaster, intersects ) { 32811 32812 matrixPosition.setFromMatrixPosition( this.matrixWorld ); 32813 32814 var distance = raycaster.ray.origin.distanceTo( matrixPosition ); 32815 32816 this.getObjectForDistance( distance ).raycast( raycaster, intersects ); 32817 32818 }; 32819 32820 }() ), 32821 32822 update: function () { 32823 32824 var v1 = new Vector3(); 32825 var v2 = new Vector3(); 32826 32827 return function update( camera ) { 32828 32829 var levels = this.levels; 32830 32831 if ( levels.length > 1 ) { 32832 32833 v1.setFromMatrixPosition( camera.matrixWorld ); 32834 v2.setFromMatrixPosition( this.matrixWorld ); 32835 32836 var distance = v1.distanceTo( v2 ); 32837 32838 levels[ 0 ].object.visible = true; 32839 32840 for ( var i = 1, l = levels.length; i < l; i ++ ) { 32841 32842 if ( distance >= levels[ i ].distance ) { 32843 32844 levels[ i - 1 ].object.visible = false; 32845 levels[ i ].object.visible = true; 32846 32847 } else { 32848 32849 break; 32850 32851 } 32852 32853 } 32854 32855 for ( ; i < l; i ++ ) { 32856 32857 levels[ i ].object.visible = false; 32858 32859 } 32860 32861 } 32862 32863 }; 32864 32865 }(), 32866 32867 toJSON: function ( meta ) { 32868 32869 var data = Object3D.prototype.toJSON.call( this, meta ); 32870 32871 data.object.levels = []; 32872 32873 var levels = this.levels; 32874 32875 for ( var i = 0, l = levels.length; i < l; i ++ ) { 32876 32877 var level = levels[ i ]; 32878 32879 data.object.levels.push( { 32880 object: level.object.uuid, 32881 distance: level.distance 32882 } ); 32883 32884 } 32885 32886 return data; 32887 32888 } 32889 32890 } ); 32891 32892 /** 32893 * @author mikael emtinger / http://gomo.se/ 32894 * @author alteredq / http://alteredqualia.com/ 32895 * @author michael guerrero / http://realitymeltdown.com 32896 * @author ikerr / http://verold.com 32897 */ 32898 32899 function Skeleton( bones, boneInverses ) { 32900 32901 // copy the bone array 32902 32903 bones = bones || []; 32904 32905 this.bones = bones.slice( 0 ); 32906 this.boneMatrices = new Float32Array( this.bones.length * 16 ); 32907 32908 // use the supplied bone inverses or calculate the inverses 32909 32910 if ( boneInverses === undefined ) { 32911 32912 this.calculateInverses(); 32913 32914 } else { 32915 32916 if ( this.bones.length === boneInverses.length ) { 32917 32918 this.boneInverses = boneInverses.slice( 0 ); 32919 32920 } else { 32921 32922 console.warn( 'THREE.Skeleton boneInverses is the wrong length.' ); 32923 32924 this.boneInverses = []; 32925 32926 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 32927 32928 this.boneInverses.push( new Matrix4() ); 32929 32930 } 32931 32932 } 32933 32934 } 32935 32936 } 32937 32938 Object.assign( Skeleton.prototype, { 32939
32940 calculateInverses: function () { 32941 32942 this.boneInverses = []; 32943 32944 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 32945 32946 var inverse = new Matrix4(); 32947 32948 if ( this.bones[ i ] ) { 32949 32950 inverse.getInverse( this.bones[ i ].matrixWorld ); 32951 32952 } 32953 32954 this.boneInverses.push( inverse ); 32955 32956 } 32957 32958 }, 32959 32960 pose: function () { 32961 32962 var bone, i, il; 32963 32964 // recover the bind-time world matrices 32965 32966 for ( i = 0, il = this.bones.length; i < il; i ++ ) { 32967 32968 bone = this.bones[ i ]; 32969 32970 if ( bone ) { 32971 32972 bone.matrixWorld.getInverse( this.boneInverses[ i ] ); 32973 32974 } 32975 32976 } 32977 32978 // compute the local matrices, positions, rotations and scales 32979 32980 for ( i = 0, il = this.bones.length; i < il; i ++ ) { 32981 32982 bone = this.bones[ i ]; 32983 32984 if ( bone ) { 32985 32986 if ( bone.parent && bone.parent.isBone ) { 32987 32988 bone.matrix.getInverse( bone.parent.matrixWorld ); 32989 bone.matrix.multiply( bone.matrixWorld ); 32990 32991 } else { 32992 32993 bone.matrix.copy( bone.matrixWorld ); 32994 32995 } 32996 32997 bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); 32998 32999 } 33000 33001 } 33002 33003 }, 33004 33005 update: ( function () { 33006 33007 var offsetMatrix = new Matrix4(); 33008 var identityMatrix = new Matrix4(); 33009 33010 return function update() { 33011 33012 var bones = this.bones; 33013 var boneInverses = this.boneInverses; 33014 var boneMatrices = this.boneMatrices; 33015 var boneTexture = this.boneTexture; 33016 33017 // flatten bone matrices to array 33018 33019 for ( var i = 0, il = bones.length; i < il; i ++ ) { 33020 33021 // compute the offset between the current and the original transform 33022 33023 var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix; 33024 33025 offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); 33026 offsetMatrix.toArray( boneMatrices, i * 16 ); 33027 33028 } 33029 33030 if ( boneTexture !== undefined ) { 33031 33032 boneTexture.needsUpdate = true; 33033 33034 } 33035 33036 }; 33037 33038 } )(), 33039 33040 clone: function () { 33041 33042 return new Skeleton( this.bones, this.boneInverses ); 33043 33044 }, 33045 33046 getBoneByName: function ( name ) { 33047 33048 for ( var i = 0, il = this.bones.length; i < il; i ++ ) { 33049 33050 var bone = this.bones[ i ]; 33051 33052 if ( bone.name === name ) { 33053 33054 return bone; 33055 33056 } 33057 33058 } 33059 33060 return undefined; 33061 33062 } 33063 33064 } ); 33065 33066 /** 33067 * @author mikael emtinger / http://gomo.se/ 33068 * @author alteredq / http://alteredqualia.com/ 33069 * @author ikerr / http://verold.com 33070 */ 33071 33072 function Bone() { 33073 33074 Object3D.call( this ); 33075 33076 this.type = 'Bone'; 33077 33078 } 33079 33080 Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { 33081 33082 constructor: Bone, 33083 33084 isBone: true 33085 33086 } ); 33087 33088 /** 33089 * @author mikael emtinger / http://gomo.se/ 33090 * @author alteredq / http://alteredqualia.com/ 33091 * @author ikerr / http://verold.com 33092 */ 33093 33094 function SkinnedMesh( geometry, material ) { 33095 33096 Mesh.call( this, geometry, material ); 33097 33098 this.type = 'SkinnedMesh'; 33099 33100 this.bindMode = 'attached'; 33101 this.bindMatrix = new Matrix4(); 33102 this.bindMatrixInverse = new Matrix4(); 33103 33104 var bones = this.initBones(); 33105 var skeleton = new Skeleton( bones ); 33106 33107 this.bind( skeleton, this.matrixWorld ); 33108 33109 this.normalizeSkinWeights(); 33110 33111 } 33112 33113 SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { 33114 33115 constructor: SkinnedMesh, 33116 33117 isSkinnedMesh: true, 33118 33119 initBones: function () { 33120 33121 var bones = [], bone, gbone; 33122 var i, il; 33123 33124 if ( this.geometry && this.geometry.bones !== undefined ) { 33125 33126 // first, create array of 'Bone' objects from geometry data 33127 33128 for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { 33129 33130 gbone = this.geometry.bones[ i ]; 33131 33132 // create new 'Bone' object 33133 33134 bone = new Bone(); 33135 bones.push( bone ); 33136 33137 // apply values 33138 33139 bone.name = gbone.name; 33140 bone.position.fromArray( gbone.pos ); 33141 bone.quaternion.fromArray( gbone.rotq ); 33142 if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl ); 33143 33144 } 33145 33146 // second, create bone hierarchy 33147 33148 for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { 33149 33150 gbone = this.geometry.bones[ i ]; 33151 33152 if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) { 33153 33154 // subsequent bones in the hierarchy 33155 33156 bones[ gbone.parent ].add( bones[ i ] ); 33157 33158 } else { 33159
33160 // topmost bone, immediate child of the skinned mesh 33161 33162 this.add( bones[ i ] ); 33163 33164 } 33165 33166 } 33167 33168 } 33169 33170 // now the bones are part of the scene graph and children of the skinned mesh. 33171 // let's update the corresponding matrices 33172 33173 this.updateMatrixWorld( true ); 33174 33175 return bones; 33176 33177 }, 33178 33179 bind: function ( skeleton, bindMatrix ) { 33180 33181 this.skeleton = skeleton; 33182 33183 if ( bindMatrix === undefined ) { 33184 33185 this.updateMatrixWorld( true ); 33186 33187 this.skeleton.calculateInverses(); 33188 33189 bindMatrix = this.matrixWorld; 33190 33191 } 33192 33193 this.bindMatrix.copy( bindMatrix ); 33194 this.bindMatrixInverse.getInverse( bindMatrix ); 33195 33196 }, 33197 33198 pose: function () { 33199 33200 this.skeleton.pose(); 33201 33202 }, 33203 33204 normalizeSkinWeights: function () { 33205 33206 var scale, i; 33207 33208 if ( this.geometry && this.geometry.isGeometry ) { 33209 33210 for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) { 33211 33212 var sw = this.geometry.skinWeights[ i ]; 33213 33214 scale = 1.0 / sw.manhattanLength(); 33215 33216 if ( scale !== Infinity ) { 33217 33218 sw.multiplyScalar( scale ); 33219 33220 } else { 33221 33222 sw.set( 1, 0, 0, 0 );
vendor: 11,272 bytes, lines 33222-33711
33222 // do something reasonable 33223 33224 } 33225 33226 } 33227 33228 } else if ( this.geometry && this.geometry.isBufferGeometry ) { 33229 33230 var vec = new Vector4(); 33231 33232 var skinWeight = this.geometry.attributes.skinWeight; 33233 33234 for ( i = 0; i < skinWeight.count; i ++ ) { 33235 33236 vec.x = skinWeight.getX( i ); 33237 vec.y = skinWeight.getY( i ); 33238 vec.z = skinWeight.getZ( i ); 33239 vec.w = skinWeight.getW( i ); 33240 33241 scale = 1.0 / vec.manhattanLength(); 33242 33243 if ( scale !== Infinity ) { 33244 33245 vec.multiplyScalar( scale ); 33246 33247 } else { 33248 33249 vec.set( 1, 0, 0, 0 ); // do something reasonable 33250 33251 } 33252 33253 skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w ); 33254 33255 } 33256 33257 } 33258 33259 }, 33260 33261 updateMatrixWorld: function ( force ) { 33262 33263 Mesh.prototype.updateMatrixWorld.call( this, force ); 33264 33265 if ( this.bindMode === 'attached' ) { 33266 33267 this.bindMatrixInverse.getInverse( this.matrixWorld ); 33268 33269 } else if ( this.bindMode === 'detached' ) { 33270 33271 this.bindMatrixInverse.getInverse( this.bindMatrix ); 33272 33273 } else { 33274 33275 console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode ); 33276 33277 } 33278 33279 }, 33280 33281 clone: function () { 33282 33283 return new this.constructor( this.geometry, this.material ).copy( this ); 33284 33285 } 33286 33287 } ); 33288 33289 /** 33290 * @author mrdoob / http://mrdoob.com/ 33291 * @author alteredq / http://alteredqualia.com/ 33292 * 33293 * parameters = { 33294 * color: <hex>, 33295 * opacity: <float>, 33296 * 33297 * linewidth: <float>, 33298 * linecap: "round", 33299 * linejoin: "round" 33300 * } 33301 */ 33302 33303 function LineBasicMaterial( parameters ) { 33304 33305 Material.call( this ); 33306 33307 this.type = 'LineBasicMaterial'; 33308 33309 this.color = new Color( 0xffffff ); 33310 33311 this.linewidth = 1; 33312 this.linecap = 'round'; 33313 this.linejoin = 'round'; 33314 33315 this.lights = false; 33316 33317 this.setValues( parameters ); 33318 33319 } 33320 33321 LineBasicMaterial.prototype = Object.create( Material.prototype ); 33322 LineBasicMaterial.prototype.constructor = LineBasicMaterial; 33323 33324 LineBasicMaterial.prototype.isLineBasicMaterial = true; 33325 33326 LineBasicMaterial.prototype.copy = function ( source ) { 33327 33328 Material.prototype.copy.call( this, source ); 33329 33330 this.color.copy( source.color ); 33331 33332 this.linewidth = source.linewidth; 33333 this.linecap = source.linecap; 33334 this.linejoin = source.linejoin; 33335 33336 return this; 33337 33338 }; 33339 33340 /** 33341 * @author mrdoob / http://mrdoob.com/ 33342 */ 33343 33344 function Line( geometry, material, mode ) { 33345 33346 if ( mode === 1 ) { 33347 33348 console.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' ); 33349 return new LineSegments( geometry, material ); 33350 33351 } 33352 33353 Object3D.call( this ); 33354 33355 this.type = 'Line'; 33356 33357 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 33358 this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } ); 33359 33360 } 33361 33362 Line.prototype = Object.assign( Object.create( Object3D.prototype ), { 33363 33364 constructor: Line, 33365 33366 isLine: true, 33367 33368 computeLineDistances: ( function () { 33369 33370 var start = new Vector3(); 33371 var end = new Vector3(); 33372 33373 return function computeLineDistances() { 33374 33375 var geometry = this.geometry; 33376 33377 if ( geometry.isBufferGeometry ) { 33378 33379 // we assume non-indexed geometry 33380 33381 if ( geometry.index === null ) { 33382 33383 var positionAttribute = geometry.attributes.position; 33384 var lineDistances = [ 0 ]; 33385 33386 for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { 33387 33388 start.fromBufferAttribute( positionAttribute, i - 1 ); 33389 end.fromBufferAttribute( positionAttribute, i ); 33390 33391 lineDistances[ i ] = lineDistances[ i - 1 ]; 33392 lineDistances[ i ] += start.distanceTo( end ); 33393 33394 } 33395 33396 geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); 33397 33398 } else { 33399 33400 console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); 33401 33402 } 33403 33404 } else if ( geometry.isGeometry ) { 33405 33406 var vertices = geometry.vertices; 33407 var lineDistances = geometry.lineDistances; 33408 33409 lineDistances[ 0 ] = 0; 33410 33411 for ( var i = 1, l = vertices.length; i < l; i ++ ) { 33412 33413 lineDistances[ i ] = lineDistances[ i - 1 ]; 33414 lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); 33415 33416 } 33417 33418 } 33419 33420 return this; 33421 33422 }; 33423 33424 }() ), 33425 33426 raycast: ( function () { 33427 33428 var inverseMatrix = new Matrix4(); 33429 var ray = new Ray(); 33430 var sphere = new Sphere(); 33431 33432 return function raycast( raycaster, intersects ) { 33433 33434 var precision = raycaster.linePrecision; 33435 var precisionSq = precision * precision; 33436 33437 var geometry = this.geometry; 33438 var matrixWorld = this.matrixWorld; 33439 33440 // Checking boundingSphere distance to ray 33441 33442 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 33443 33444 sphere.copy( geometry.boundingSphere ); 33445 sphere.applyMatrix4( matrixWorld ); 33446 33447 if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; 33448 33449 // 33450 33451 inverseMatrix.getInverse( matrixWorld ); 33452 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 33453 33454 var vStart = new Vector3(); 33455 var vEnd = new Vector3(); 33456 var interSegment = new Vector3(); 33457 var interRay = new Vector3(); 33458 var step = ( this && this.isLineSegments ) ? 2 : 1; 33459 33460 if ( geometry.isBufferGeometry ) { 33461 33462 var index = geometry.index; 33463 var attributes = geometry.attributes; 33464 var positions = attributes.position.array; 33465 33466 if ( index !== null ) { 33467 33468 var indices = index.array; 33469 33470 for ( var i = 0, l = indices.length - 1; i < l; i += step ) { 33471 33472 var a = indices[ i ]; 33473 var b = indices[ i + 1 ]; 33474 33475 vStart.fromArray( positions, a * 3 ); 33476 vEnd.fromArray( positions, b * 3 ); 33477 33478 var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); 33479 33480 if ( distSq > precisionSq ) continue; 33481 33482 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 33483 33484 var distance = raycaster.ray.origin.distanceTo( interRay ); 33485 33486 if ( distance < raycaster.near || distance > raycaster.far ) continue; 33487 33488 intersects.push( { 33489 33490 distance: distance, 33491 // What do we want? intersection point on the ray or on the segment?? 33492 // point: raycaster.ray.at( distance ), 33493 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 33494 index: i, 33495 face: null, 33496 faceIndex: null, 33497 object: this 33498 33499 } ); 33500 33501 } 33502 33503 } else { 33504 33505 for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { 33506 33507 vStart.fromArray( positions, 3 * i ); 33508 vEnd.fromArray( positions, 3 * i + 3 ); 33509 33510 var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); 33511 33512 if ( distSq > precisionSq ) continue; 33513 33514 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 33515 33516 var distance = raycaster.ray.origin.distanceTo( interRay ); 33517 33518 if ( distance < raycaster.near || distance > raycaster.far ) continue; 33519 33520 intersects.push( { 33521 33522 distance: distance, 33523 // What do we want? intersection point on the ray or on the segment?? 33524 // point: raycaster.ray.at( distance ), 33525 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 33526 index: i, 33527 face: null, 33528 faceIndex: null, 33529 object: this 33530 33531 } ); 33532 33533 } 33534 33535 } 33536 33537 } else if ( geometry.isGeometry ) { 33538 33539 var vertices = geometry.vertices; 33540 var nbVertices = vertices.length; 33541 33542 for ( var i = 0; i < nbVertices - 1; i += step ) { 33543 33544 var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); 33545 33546 if ( distSq > precisionSq ) continue; 33547 33548 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation 33549 33550 var distance = raycaster.ray.origin.distanceTo( interRay ); 33551 33552 if ( distance < raycaster.near || distance > raycaster.far ) continue; 33553 33554 intersects.push( { 33555 33556 distance: distance, 33557 // What do we want? intersection point on the ray or on the segment?? 33558 // point: raycaster.ray.at( distance ), 33559 point: interSegment.clone().applyMatrix4( this.matrixWorld ), 33560 index: i, 33561 face: null, 33562 faceIndex: null, 33563 object: this 33564 33565 } ); 33566 33567 } 33568 33569 } 33570 33571 }; 33572 33573 }() ), 33574 33575 clone: function () { 33576 33577 return new this.constructor( this.geometry, this.material ).copy( this ); 33578 33579 } 33580 33581 } ); 33582 33583 /** 33584 * @author mrdoob / http://mrdoob.com/ 33585 */ 33586 33587 function LineSegments( geometry, material ) { 33588 33589 Line.call( this, geometry, material ); 33590 33591 this.type = 'LineSegments'; 33592 33593 } 33594 33595 LineSegments.prototype = Object.assign( Object.create( Line.prototype ), { 33596 33597 constructor: LineSegments, 33598 33599 isLineSegments: true, 33600 33601 computeLineDistances: ( function () { 33602 33603 var start = new Vector3(); 33604 var end = new Vector3(); 33605 33606 return function computeLineDistances() { 33607 33608 var geometry = this.geometry; 33609 33610 if ( geometry.isBufferGeometry ) { 33611 33612 // we assume non-indexed geometry 33613 33614 if ( geometry.index === null ) { 33615 33616 var positionAttribute = geometry.attributes.position; 33617 var lineDistances = []; 33618 33619 for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { 33620 33621 start.fromBufferAttribute( positionAttribute, i ); 33622 end.fromBufferAttribute( positionAttribute, i + 1 ); 33623 33624 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; 33625 lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); 33626 33627 } 33628 33629 geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); 33630 33631 } else { 33632 33633 console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); 33634 33635 } 33636 33637 } else if ( geometry.isGeometry ) { 33638 33639 var vertices = geometry.vertices; 33640 var lineDistances = geometry.lineDistances; 33641 33642 for ( var i = 0, l = vertices.length; i < l; i += 2 ) { 33643 33644 start.copy( vertices[ i ] ); 33645 end.copy( vertices[ i + 1 ] ); 33646 33647 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; 33648 lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); 33649 33650 } 33651 33652 } 33653 33654 return this; 33655 33656 }; 33657 33658 }() ) 33659 33660 } ); 33661 33662 /** 33663 * @author mgreter / http://github.com/mgreter 33664 */ 33665 33666 function LineLoop( geometry, material ) { 33667 33668 Line.call( this, geometry, material ); 33669 33670 this.type = 'LineLoop'; 33671 33672 } 33673 33674 LineLoop.prototype = Object.assign( Object.create( Line.prototype ), { 33675 33676 constructor: LineLoop, 33677 33678 isLineLoop: true, 33679 33680 } ); 33681 33682 /** 33683 * @author mrdoob / http://mrdoob.com/ 33684 * @author alteredq / http://alteredqualia.com/ 33685 * 33686 * parameters = { 33687 * color: <hex>, 33688 * opacity: <float>, 33689 * map: new THREE.Texture( <Image> ), 33690 * 33691 * size: <float>, 33692 * sizeAttenuation: <bool> 33693 * 33694 * morphTargets: <bool> 33695 * } 33696 */ 33697 33698 function PointsMaterial( parameters ) { 33699 33700 Material.call( this ); 33701 33702 this.type = 'PointsMaterial'; 33703 33704 this.color = new Color( 0xffffff ); 33705 33706 this.map = null; 33707 33708 this.size = 1; 33709 this.sizeAttenuation = true; 33710 33711 this.morphTargets = false;
33712 33713 this.lights = false; 33714 33715 this.setValues( parameters ); 33716 33717 } 33718 33719 PointsMaterial.prototype = Object.create( Material.prototype ); 33720 PointsMaterial.prototype.constructor = PointsMaterial; 33721 33722 PointsMaterial.prototype.isPointsMaterial = true; 33723 33724 PointsMaterial.prototype.copy = function ( source ) { 33725 33726 Material.prototype.copy.call( this, source ); 33727 33728 this.color.copy( source.color ); 33729 33730 this.map = source.map; 33731 33732 this.size = source.size; 33733 this.sizeAttenuation = source.sizeAttenuation; 33734 33735 this.morphTargets = source.morphTargets; 33736 33737 return this; 33738 33739 }; 33740 33741 /** 33742 * @author alteredq / http://alteredqualia.com/ 33743 */ 33744 33745 function Points( geometry, material ) { 33746 33747 Object3D.call( this ); 33748 33749 this.type = 'Points'; 33750 33751 this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); 33752 this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); 33753 33754 } 33755 33756 Points.prototype = Object.assign( Object.create( Object3D.prototype ), { 33757 33758 constructor: Points, 33759 33760 isPoints: true, 33761 33762 raycast: ( function () { 33763 33764 var inverseMatrix = new Matrix4(); 33765 var ray = new Ray(); 33766 var sphere = new Sphere(); 33767 33768 return function raycast( raycaster, intersects ) { 33769 33770 var object = this; 33771 var geometry = this.geometry; 33772 var matrixWorld = this.matrixWorld; 33773 var threshold = raycaster.params.Points.threshold; 33774 33775 // Checking boundingSphere distance to ray 33776 33777 if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); 33778 33779 sphere.copy( geometry.boundingSphere ); 33780 sphere.applyMatrix4( matrixWorld ); 33781 sphere.radius += threshold; 33782 33783 if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; 33784 33785 // 33786 33787 inverseMatrix.getInverse( matrixWorld ); 33788 ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); 33789 33790 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); 33791 var localThresholdSq = localThreshold * localThreshold; 33792 var position = new Vector3(); 33793 var intersectPoint = new Vector3(); 33794 33795 function testPoint( point, index ) { 33796 33797 var rayPointDistanceSq = ray.distanceSqToPoint( point ); 33798 33799 if ( rayPointDistanceSq < localThresholdSq ) { 33800 33801 ray.closestPointToPoint( point, intersectPoint ); 33802 intersectPoint.applyMatrix4( matrixWorld ); 33803 33804 var distance = raycaster.ray.origin.distanceTo( intersectPoint ); 33805 33806 if ( distance < raycaster.near || distance > raycaster.far ) return; 33807 33808 intersects.push( { 33809 33810 distance: distance, 33811 distanceToRay: Math.sqrt( rayPointDistanceSq ), 33812 point: intersectPoint.clone(), 33813 index: index, 33814 face: null, 33815 object: object 33816 33817 } ); 33818 33819 } 33820 33821 } 33822 33823 if ( geometry.isBufferGeometry ) { 33824 33825 var index = geometry.index; 33826 var attributes = geometry.attributes; 33827 var positions = attributes.position.array; 33828 33829 if ( index !== null ) { 33830 33831 var indices = index.array; 33832 33833 for ( var i = 0, il = indices.length; i < il; i ++ ) { 33834 33835 var a = indices[ i ]; 33836 33837 position.fromArray( positions, a * 3 ); 33838 33839 testPoint( position, a ); 33840 33841 } 33842 33843 } else { 33844 33845 for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { 33846 33847 position.fromArray( positions, i * 3 ); 33848 33849 testPoint( position, i ); 33850 33851 } 33852 33853 } 33854 33855 } else { 33856 33857 var vertices = geometry.vertices; 33858 33859 for ( var i = 0, l = vertices.length; i < l; i ++ ) { 33860 33861 testPoint( vertices[ i ], i ); 33862 33863 } 33864 33865 } 33866 33867 }; 33868 33869 }() ), 33870 33871 clone: function () { 33872 33873 return new this.constructor( this.geometry, this.material ).copy( this ); 33874 33875 } 33876 33877 } ); 33878 33879 /** 33880 * @author mrdoob / http://mrdoob.com/ 33881 */ 33882 33883 function Group() { 33884 33885 Object3D.call( this ); 33886 33887 this.type = 'Group'; 33888 33889 } 33890 33891 Group.prototype = Object.assign( Object.create( Object3D.prototype ), { 33892 33893 constructor: Group, 33894 33895 isGroup: true 33896 33897 } ); 33898 33899 /** 33900 * @author mrdoob / http://mrdoob.com/ 33901 */ 33902 33903 function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { 33904 33905 Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 33906 33907 this.generateMipmaps = false;
vendor: 36,999 bytes, lines 33908-35504
33908 33909 } 33910 33911 VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), { 33912 33913 constructor: VideoTexture, 33914 33915 isVideoTexture: true, 33916 33917 update: function () { 33918 33919 var video = this.image; 33920 33921 if ( video.readyState >= video.HAVE_CURRENT_DATA ) { 33922 33923 this.needsUpdate = true; 33924 33925 } 33926 33927 } 33928 33929 } ); 33930 33931 /** 33932 * @author alteredq / http://alteredqualia.com/ 33933 */ 33934 33935 function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { 33936 33937 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 33938 33939 this.image = { width: width, height: height }; 33940 this.mipmaps = mipmaps; 33941 33942 // no flipping for cube textures 33943 // (also flipping doesn't work for compressed textures ) 33944 33945 this.flipY = false; 33946 33947 // can't generate mipmaps for compressed textures 33948 // mips must be embedded in DDS files 33949 33950 this.generateMipmaps = false; 33951 33952 } 33953 33954 CompressedTexture.prototype = Object.create( Texture.prototype ); 33955 CompressedTexture.prototype.constructor = CompressedTexture; 33956 33957 CompressedTexture.prototype.isCompressedTexture = true; 33958 33959 /** 33960 * @author Matt DesLauriers / @mattdesl 33961 * @author atix / arthursilber.de 33962 */ 33963 33964 function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) { 33965 33966 format = format !== undefined ? format : DepthFormat; 33967 33968 if ( format !== DepthFormat && format !== DepthStencilFormat ) { 33969 33970 throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' ); 33971 33972 } 33973 33974 if ( type === undefined && format === DepthFormat ) type = UnsignedShortType; 33975 if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type; 33976 33977 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); 33978 33979 this.image = { width: width, height: height }; 33980 33981 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; 33982 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; 33983 33984 this.flipY = false; 33985 this.generateMipmaps = false; 33986 33987 } 33988 33989 DepthTexture.prototype = Object.create( Texture.prototype ); 33990 DepthTexture.prototype.constructor = DepthTexture; 33991 DepthTexture.prototype.isDepthTexture = true; 33992 33993 /** 33994 * @author mrdoob / http://mrdoob.com/ 33995 * @author Mugen87 / https://github.com/Mugen87 33996 */ 33997 33998 function WireframeGeometry( geometry ) { 33999 34000 BufferGeometry.call( this ); 34001 34002 this.type = 'WireframeGeometry'; 34003 34004 // buffer 34005 34006 var vertices = []; 34007 34008 // helper variables 34009 34010 var i, j, l, o, ol; 34011 var edge = [ 0, 0 ], edges = {}, e, edge1, edge2; 34012 var key, keys = [ 'a', 'b', 'c' ]; 34013 var vertex; 34014 34015 // different logic for Geometry and BufferGeometry 34016 34017 if ( geometry && geometry.isGeometry ) { 34018 34019 // create a data structure that contains all edges without duplicates 34020 34021 var faces = geometry.faces; 34022 34023 for ( i = 0, l = faces.length; i < l; i ++ ) { 34024 34025 var face = faces[ i ]; 34026 34027 for ( j = 0; j < 3; j ++ ) { 34028 34029 edge1 = face[ keys[ j ] ]; 34030 edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; 34031 edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates 34032 edge[ 1 ] = Math.max( edge1, edge2 ); 34033 34034 key = edge[ 0 ] + ',' + edge[ 1 ]; 34035 34036 if ( edges[ key ] === undefined ) { 34037 34038 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; 34039 34040 } 34041 34042 } 34043 34044 } 34045 34046 // generate vertices 34047 34048 for ( key in edges ) { 34049 34050 e = edges[ key ]; 34051 34052 vertex = geometry.vertices[ e.index1 ]; 34053 vertices.push( vertex.x, vertex.y, vertex.z ); 34054 34055 vertex = geometry.vertices[ e.index2 ]; 34056 vertices.push( vertex.x, vertex.y, vertex.z ); 34057 34058 } 34059 34060 } else if ( geometry && geometry.isBufferGeometry ) { 34061 34062 var position, indices, groups; 34063 var group, start, count; 34064 var index1, index2; 34065 34066 vertex = new Vector3(); 34067 34068 if ( geometry.index !== null ) { 34069 34070 // indexed BufferGeometry 34071 34072 position = geometry.attributes.position; 34073 indices = geometry.index; 34074 groups = geometry.groups; 34075 34076 if ( groups.length === 0 ) { 34077 34078 groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; 34079 34080 } 34081 34082 // create a data structure that contains all eges without duplicates 34083 34084 for ( o = 0, ol = groups.length; o < ol; ++ o ) { 34085 34086 group = groups[ o ]; 34087 34088 start = group.start; 34089 count = group.count; 34090 34091 for ( i = start, l = ( start + count ); i < l; i += 3 ) { 34092 34093 for ( j = 0; j < 3; j ++ ) { 34094 34095 edge1 = indices.getX( i + j ); 34096 edge2 = indices.getX( i + ( j + 1 ) % 3 ); 34097 edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates 34098 edge[ 1 ] = Math.max( edge1, edge2 ); 34099 34100 key = edge[ 0 ] + ',' + edge[ 1 ]; 34101 34102 if ( edges[ key ] === undefined ) { 34103 34104 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; 34105 34106 } 34107 34108 } 34109 34110 } 34111 34112 } 34113 34114 // generate vertices 34115 34116 for ( key in edges ) { 34117 34118 e = edges[ key ]; 34119 34120 vertex.fromBufferAttribute( position, e.index1 ); 34121 vertices.push( vertex.x, vertex.y, vertex.z ); 34122 34123 vertex.fromBufferAttribute( position, e.index2 ); 34124 vertices.push( vertex.x, vertex.y, vertex.z ); 34125 34126 } 34127 34128 } else { 34129 34130 // non-indexed BufferGeometry 34131 34132 position = geometry.attributes.position; 34133 34134 for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) { 34135 34136 for ( j = 0; j < 3; j ++ ) { 34137 34138 // three edges per triangle, an edge is represented as (index1, index2) 34139 // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) 34140 34141 index1 = 3 * i + j; 34142 vertex.fromBufferAttribute( position, index1 ); 34143 vertices.push( vertex.x, vertex.y, vertex.z ); 34144 34145 index2 = 3 * i + ( ( j + 1 ) % 3 ); 34146 vertex.fromBufferAttribute( position, index2 ); 34147 vertices.push( vertex.x, vertex.y, vertex.z ); 34148 34149 } 34150 34151 } 34152 34153 } 34154 34155 } 34156 34157 // build geometry 34158 34159 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 34160 34161 } 34162 34163 WireframeGeometry.prototype = Object.create( BufferGeometry.prototype ); 34164 WireframeGeometry.prototype.constructor = WireframeGeometry; 34165 34166 /** 34167 * @author zz85 / https://github.com/zz85 34168 * @author Mugen87 / https://github.com/Mugen87 34169 * 34170 * Parametric Surfaces Geometry 34171 * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 34172 */ 34173 34174 // ParametricGeometry 34175 34176 function ParametricGeometry( func, slices, stacks ) { 34177 34178 Geometry.call( this ); 34179 34180 this.type = 'ParametricGeometry'; 34181 34182 this.parameters = { 34183 func: func, 34184 slices: slices, 34185 stacks: stacks 34186 }; 34187 34188 this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) ); 34189 this.mergeVertices(); 34190 34191 } 34192 34193 ParametricGeometry.prototype = Object.create( Geometry.prototype ); 34194 ParametricGeometry.prototype.constructor = ParametricGeometry; 34195 34196 // ParametricBufferGeometry 34197 34198 function ParametricBufferGeometry( func, slices, stacks ) { 34199 34200 BufferGeometry.call( this ); 34201 34202 this.type = 'ParametricBufferGeometry'; 34203 34204 this.parameters = { 34205 func: func, 34206 slices: slices, 34207 stacks: stacks 34208 }; 34209 34210 // buffers 34211 34212 var indices = []; 34213 var vertices = []; 34214 var normals = []; 34215 var uvs = []; 34216 34217 var EPS = 0.00001; 34218 34219 var normal = new Vector3(); 34220 34221 var p0 = new Vector3(), p1 = new Vector3(); 34222 var pu = new Vector3(), pv = new Vector3(); 34223 34224 var i, j; 34225 34226 if ( func.length < 3 ) { 34227 34228 console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' ); 34229 34230 } 34231 34232 // generate vertices, normals and uvs 34233 34234 var sliceCount = slices + 1; 34235 34236 for ( i = 0; i <= stacks; i ++ ) { 34237 34238 var v = i / stacks; 34239 34240 for ( j = 0; j <= slices; j ++ ) { 34241 34242 var u = j / slices; 34243 34244 // vertex 34245 34246 func( u, v, p0 ); 34247 vertices.push( p0.x, p0.y, p0.z ); 34248 34249 // normal 34250 34251 // approximate tangent vectors via finite differences 34252 34253 if ( u - EPS >= 0 ) { 34254 34255 func( u - EPS, v, p1 ); 34256 pu.subVectors( p0, p1 ); 34257 34258 } else { 34259 34260 func( u + EPS, v, p1 ); 34261 pu.subVectors( p1, p0 ); 34262 34263 } 34264 34265 if ( v - EPS >= 0 ) { 34266 34267 func( u, v - EPS, p1 ); 34268 pv.subVectors( p0, p1 ); 34269 34270 } else { 34271 34272 func( u, v + EPS, p1 ); 34273 pv.subVectors( p1, p0 ); 34274 34275 } 34276 34277 // cross product of tangent vectors returns surface normal 34278 34279 normal.crossVectors( pu, pv ).normalize(); 34280 normals.push( normal.x, normal.y, normal.z ); 34281 34282 // uv 34283 34284 uvs.push( u, v ); 34285 34286 } 34287 34288 } 34289 34290 // generate indices 34291 34292 for ( i = 0; i < stacks; i ++ ) { 34293 34294 for ( j = 0; j < slices; j ++ ) { 34295 34296 var a = i * sliceCount + j; 34297 var b = i * sliceCount + j + 1; 34298 var c = ( i + 1 ) * sliceCount + j + 1; 34299 var d = ( i + 1 ) * sliceCount + j; 34300 34301 // faces one and two 34302 34303 indices.push( a, b, d ); 34304 indices.push( b, c, d ); 34305 34306 } 34307 34308 } 34309 34310 // build geometry 34311 34312 this.setIndex( indices ); 34313 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 34314 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 34315 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 34316 34317 } 34318 34319 ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 34320 ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; 34321 34322 /** 34323 * @author clockworkgeek / https://github.com/clockworkgeek 34324 * @author timothypratley / https://github.com/timothypratley 34325 * @author WestLangley / http://github.com/WestLangley 34326 * @author Mugen87 / https://github.com/Mugen87 34327 */ 34328 34329 // PolyhedronGeometry 34330 34331 function PolyhedronGeometry( vertices, indices, radius, detail ) { 34332 34333 Geometry.call( this ); 34334 34335 this.type = 'PolyhedronGeometry'; 34336 34337 this.parameters = { 34338 vertices: vertices, 34339 indices: indices, 34340 radius: radius, 34341 detail: detail 34342 }; 34343 34344 this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) ); 34345 this.mergeVertices(); 34346 34347 } 34348 34349 PolyhedronGeometry.prototype = Object.create( Geometry.prototype ); 34350 PolyhedronGeometry.prototype.constructor = PolyhedronGeometry; 34351 34352 // PolyhedronBufferGeometry 34353 34354 function PolyhedronBufferGeometry( vertices, indices, radius, detail ) { 34355 34356 BufferGeometry.call( this ); 34357 34358 this.type = 'PolyhedronBufferGeometry'; 34359 34360 this.parameters = { 34361 vertices: vertices, 34362 indices: indices, 34363 radius: radius, 34364 detail: detail 34365 }; 34366 34367 radius = radius || 1; 34368 detail = detail || 0; 34369 34370 // default buffer data 34371 34372 var vertexBuffer = []; 34373 var uvBuffer = []; 34374 34375 // the subdivision creates the vertex buffer data 34376 34377 subdivide( detail ); 34378 34379 // all vertices should lie on a conceptual sphere with a given radius 34380 34381 appplyRadius( radius ); 34382 34383 // finally, create the uv data 34384 34385 generateUVs(); 34386 34387 // build non-indexed geometry 34388 34389 this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); 34390 this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); 34391 this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); 34392 34393 if ( detail === 0 ) { 34394 34395 this.computeVertexNormals(); // flat normals 34396 34397 } else { 34398 34399 this.normalizeNormals(); // smooth normals 34400 34401 } 34402 34403 // helper functions 34404 34405 function subdivide( detail ) { 34406 34407 var a = new Vector3(); 34408 var b = new Vector3(); 34409 var c = new Vector3(); 34410 34411 // iterate over all faces and apply a subdivison with the given detail value 34412 34413 for ( var i = 0; i < indices.length; i += 3 ) { 34414 34415 // get the vertices of the face 34416 34417 getVertexByIndex( indices[ i + 0 ], a ); 34418 getVertexByIndex( indices[ i + 1 ], b ); 34419 getVertexByIndex( indices[ i + 2 ], c ); 34420 34421 // perform subdivision 34422 34423 subdivideFace( a, b, c, detail ); 34424 34425 } 34426 34427 } 34428 34429 function subdivideFace( a, b, c, detail ) { 34430 34431 var cols = Math.pow( 2, detail ); 34432 34433 // we use this multidimensional array as a data structure for creating the subdivision 34434 34435 var v = []; 34436 34437 var i, j; 34438 34439 // construct all of the vertices for this subdivision 34440 34441 for ( i = 0; i <= cols; i ++ ) { 34442 34443 v[ i ] = []; 34444 34445 var aj = a.clone().lerp( c, i / cols ); 34446 var bj = b.clone().lerp( c, i / cols ); 34447 34448 var rows = cols - i; 34449 34450 for ( j = 0; j <= rows; j ++ ) { 34451 34452 if ( j === 0 && i === cols ) { 34453 34454 v[ i ][ j ] = aj; 34455 34456 } else { 34457 34458 v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); 34459 34460 } 34461 34462 } 34463 34464 } 34465 34466 // construct all of the faces 34467 34468 for ( i = 0; i < cols; i ++ ) { 34469 34470 for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) { 34471 34472 var k = Math.floor( j / 2 ); 34473 34474 if ( j % 2 === 0 ) { 34475 34476 pushVertex( v[ i ][ k + 1 ] ); 34477 pushVertex( v[ i + 1 ][ k ] ); 34478 pushVertex( v[ i ][ k ] ); 34479 34480 } else { 34481 34482 pushVertex( v[ i ][ k + 1 ] ); 34483 pushVertex( v[ i + 1 ][ k + 1 ] ); 34484 pushVertex( v[ i + 1 ][ k ] ); 34485 34486 } 34487 34488 } 34489 34490 } 34491 34492 } 34493 34494 function appplyRadius( radius ) { 34495 34496 var vertex = new Vector3(); 34497 34498 // iterate over the entire buffer and apply the radius to each vertex 34499 34500 for ( var i = 0; i < vertexBuffer.length; i += 3 ) { 34501 34502 vertex.x = vertexBuffer[ i + 0 ]; 34503 vertex.y = vertexBuffer[ i + 1 ]; 34504 vertex.z = vertexBuffer[ i + 2 ]; 34505 34506 vertex.normalize().multiplyScalar( radius ); 34507 34508 vertexBuffer[ i + 0 ] = vertex.x; 34509 vertexBuffer[ i + 1 ] = vertex.y; 34510 vertexBuffer[ i + 2 ] = vertex.z; 34511 34512 } 34513 34514 } 34515 34516 function generateUVs() { 34517 34518 var vertex = new Vector3(); 34519 34520 for ( var i = 0; i < vertexBuffer.length; i += 3 ) { 34521 34522 vertex.x = vertexBuffer[ i + 0 ]; 34523 vertex.y = vertexBuffer[ i + 1 ]; 34524 vertex.z = vertexBuffer[ i + 2 ]; 34525 34526 var u = azimuth( vertex ) / 2 / Math.PI + 0.5; 34527 var v = inclination( vertex ) / Math.PI + 0.5; 34528 uvBuffer.push( u, 1 - v ); 34529 34530 } 34531 34532 correctUVs(); 34533 34534 correctSeam(); 34535 34536 } 34537 34538 function correctSeam() { 34539 34540 // handle case when face straddles the seam, see #3269 34541 34542 for ( var i = 0; i < uvBuffer.length; i += 6 ) { 34543 34544 // uv data of a single face 34545 34546 var x0 = uvBuffer[ i + 0 ]; 34547 var x1 = uvBuffer[ i + 2 ]; 34548 var x2 = uvBuffer[ i + 4 ]; 34549 34550 var max = Math.max( x0, x1, x2 ); 34551 var min = Math.min( x0, x1, x2 ); 34552 34553 // 0.9 is somewhat arbitrary 34554 34555 if ( max > 0.9 && min < 0.1 ) { 34556 34557 if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; 34558 if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; 34559 if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; 34560 34561 } 34562 34563 } 34564 34565 } 34566 34567 function pushVertex( vertex ) { 34568 34569 vertexBuffer.push( vertex.x, vertex.y, vertex.z ); 34570 34571 } 34572 34573 function getVertexByIndex( index, vertex ) { 34574 34575 var stride = index * 3; 34576 34577 vertex.x = vertices[ stride + 0 ]; 34578 vertex.y = vertices[ stride + 1 ]; 34579 vertex.z = vertices[ stride + 2 ]; 34580 34581 } 34582 34583 function correctUVs() { 34584 34585 var a = new Vector3(); 34586 var b = new Vector3(); 34587 var c = new Vector3(); 34588 34589 var centroid = new Vector3(); 34590 34591 var uvA = new Vector2(); 34592 var uvB = new Vector2(); 34593 var uvC = new Vector2(); 34594 34595 for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) { 34596 34597 a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] ); 34598 b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] ); 34599 c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); 34600 34601 uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); 34602 uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); 34603 uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); 34604 34605 centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); 34606 34607 var azi = azimuth( centroid ); 34608 34609 correctUV( uvA, j + 0, a, azi ); 34610 correctUV( uvB, j + 2, b, azi ); 34611 correctUV( uvC, j + 4, c, azi ); 34612 34613 } 34614 34615 } 34616 34617 function correctUV( uv, stride, vector, azimuth ) { 34618 34619 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) { 34620 34621 uvBuffer[ stride ] = uv.x - 1; 34622 34623 } 34624 34625 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) { 34626 34627 uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5; 34628 34629 } 34630 34631 } 34632 34633 // Angle around the Y axis, counter-clockwise when looking from above. 34634 34635 function azimuth( vector ) { 34636 34637 return Math.atan2( vector.z, - vector.x ); 34638 34639 } 34640 34641 34642 // Angle above the XZ plane. 34643 34644 function inclination( vector ) { 34645 34646 return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); 34647 34648 } 34649 34650 } 34651 34652 PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 34653 PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry; 34654 34655 /** 34656 * @author timothypratley / https://github.com/timothypratley 34657 * @author Mugen87 / https://github.com/Mugen87 34658 */ 34659 34660 // TetrahedronGeometry 34661 34662 function TetrahedronGeometry( radius, detail ) { 34663 34664 Geometry.call( this ); 34665 34666 this.type = 'TetrahedronGeometry'; 34667 34668 this.parameters = { 34669 radius: radius, 34670 detail: detail 34671 }; 34672 34673 this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) ); 34674 this.mergeVertices(); 34675 34676 } 34677 34678 TetrahedronGeometry.prototype = Object.create( Geometry.prototype ); 34679 TetrahedronGeometry.prototype.constructor = TetrahedronGeometry; 34680 34681 // TetrahedronBufferGeometry 34682 34683 function TetrahedronBufferGeometry( radius, detail ) { 34684 34685 var vertices = [ 34686 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 34687 ]; 34688 34689 var indices = [ 34690 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 34691 ]; 34692 34693 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 34694 34695 this.type = 'TetrahedronBufferGeometry'; 34696 34697 this.parameters = { 34698 radius: radius, 34699 detail: detail 34700 }; 34701 34702 } 34703 34704 TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 34705 TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry; 34706 34707 /** 34708 * @author timothypratley / https://github.com/timothypratley 34709 * @author Mugen87 / https://github.com/Mugen87 34710 */ 34711 34712 // OctahedronGeometry 34713 34714 function OctahedronGeometry( radius, detail ) { 34715 34716 Geometry.call( this ); 34717 34718 this.type = 'OctahedronGeometry'; 34719 34720 this.parameters = { 34721 radius: radius, 34722 detail: detail 34723 }; 34724 34725 this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) ); 34726 this.mergeVertices(); 34727 34728 } 34729 34730 OctahedronGeometry.prototype = Object.create( Geometry.prototype ); 34731 OctahedronGeometry.prototype.constructor = OctahedronGeometry; 34732 34733 // OctahedronBufferGeometry 34734 34735 function OctahedronBufferGeometry( radius, detail ) { 34736 34737 var vertices = [ 34738 1, 0, 0, - 1, 0, 0, 0, 1, 0, 34739 0, - 1, 0, 0, 0, 1, 0, 0, - 1 34740 ]; 34741 34742 var indices = [ 34743 0, 2, 4, 0, 4, 3, 0, 3, 5, 34744 0, 5, 2, 1, 2, 5, 1, 5, 3, 34745 1, 3, 4, 1, 4, 2 34746 ]; 34747 34748 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 34749 34750 this.type = 'OctahedronBufferGeometry'; 34751 34752 this.parameters = { 34753 radius: radius, 34754 detail: detail 34755 }; 34756 34757 } 34758 34759 OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 34760 OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry; 34761 34762 /** 34763 * @author timothypratley / https://github.com/timothypratley 34764 * @author Mugen87 / https://github.com/Mugen87 34765 */ 34766 34767 // IcosahedronGeometry 34768 34769 function IcosahedronGeometry( radius, detail ) { 34770 34771 Geometry.call( this ); 34772 34773 this.type = 'IcosahedronGeometry'; 34774 34775 this.parameters = { 34776 radius: radius, 34777 detail: detail 34778 }; 34779 34780 this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) ); 34781 this.mergeVertices(); 34782 34783 } 34784 34785 IcosahedronGeometry.prototype = Object.create( Geometry.prototype ); 34786 IcosahedronGeometry.prototype.constructor = IcosahedronGeometry; 34787 34788 // IcosahedronBufferGeometry 34789 34790 function IcosahedronBufferGeometry( radius, detail ) { 34791 34792 var t = ( 1 + Math.sqrt( 5 ) ) / 2; 34793 34794 var vertices = [ 34795 - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, 34796 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 34797 t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 34798 ]; 34799 34800 var indices = [ 34801 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 34802 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 34803 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 34804 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 34805 ]; 34806 34807 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 34808 34809 this.type = 'IcosahedronBufferGeometry'; 34810 34811 this.parameters = { 34812 radius: radius, 34813 detail: detail 34814 }; 34815 34816 } 34817 34818 IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 34819 IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry; 34820 34821 /** 34822 * @author Abe Pazos / https://hamoid.com 34823 * @author Mugen87 / https://github.com/Mugen87 34824 */ 34825 34826 // DodecahedronGeometry 34827 34828 function DodecahedronGeometry( radius, detail ) { 34829 34830 Geometry.call( this ); 34831 34832 this.type = 'DodecahedronGeometry'; 34833 34834 this.parameters = { 34835 radius: radius, 34836 detail: detail 34837 }; 34838 34839 this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) ); 34840 this.mergeVertices(); 34841 34842 } 34843 34844 DodecahedronGeometry.prototype = Object.create( Geometry.prototype ); 34845 DodecahedronGeometry.prototype.constructor = DodecahedronGeometry; 34846 34847 // DodecahedronBufferGeometry 34848 34849 function DodecahedronBufferGeometry( radius, detail ) { 34850 34851 var t = ( 1 + Math.sqrt( 5 ) ) / 2; 34852 var r = 1 / t; 34853 34854 var vertices = [ 34855 34856 // (±1, ±1, ±1) 34857 - 1, - 1, - 1, - 1, - 1, 1, 34858 - 1, 1, - 1, - 1, 1, 1, 34859 1, - 1, - 1, 1, - 1, 1, 34860 1, 1, - 1, 1, 1, 1, 34861 34862 // (0, ±1/Ï, ±Ï) 34863 0, - r, - t, 0, - r, t, 34864 0, r, - t, 0, r, t, 34865 34866 // (±1/Ï, ±Ï, 0) 34867 - r, - t, 0, - r, t, 0, 34868 r, - t, 0, r, t, 0, 34869 34870 // (±Ï, 0, ±1/Ï) 34871 - t, 0, - r, t, 0, - r, 34872 - t, 0, r, t, 0, r 34873 ]; 34874 34875 var indices = [ 34876 3, 11, 7, 3, 7, 15, 3, 15, 13, 34877 7, 19, 17, 7, 17, 6, 7, 6, 15, 34878 17, 4, 8, 17, 8, 10, 17, 10, 6, 34879 8, 0, 16, 8, 16, 2, 8, 2, 10, 34880 0, 12, 1, 0, 1, 18, 0, 18, 16, 34881 6, 10, 2, 6, 2, 13, 6, 13, 15, 34882 2, 16, 18, 2, 18, 3, 2, 3, 13, 34883 18, 1, 9, 18, 9, 11, 18, 11, 3, 34884 4, 14, 12, 4, 12, 0, 4, 0, 8, 34885 11, 9, 5, 11, 5, 19, 11, 19, 7, 34886 19, 5, 14, 19, 14, 4, 19, 4, 17, 34887 1, 12, 14, 1, 14, 5, 1, 5, 9 34888 ]; 34889 34890 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); 34891 34892 this.type = 'DodecahedronBufferGeometry'; 34893 34894 this.parameters = { 34895 radius: radius, 34896 detail: detail 34897 }; 34898 34899 } 34900 34901 DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); 34902 DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry; 34903 34904 /** 34905 * @author oosmoxiecode / https://github.com/oosmoxiecode 34906 * @author WestLangley / https://github.com/WestLangley 34907 * @author zz85 / https://github.com/zz85 34908 * @author miningold / https://github.com/miningold 34909 * @author jonobr1 / https://github.com/jonobr1 34910 * @author Mugen87 / https://github.com/Mugen87 34911 * 34912 */ 34913 34914 // TubeGeometry 34915 34916 function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) { 34917 34918 Geometry.call( this ); 34919 34920 this.type = 'TubeGeometry'; 34921 34922 this.parameters = { 34923 path: path, 34924 tubularSegments: tubularSegments, 34925 radius: radius, 34926 radialSegments: radialSegments, 34927 closed: closed 34928 }; 34929 34930 if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' ); 34931 34932 var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ); 34933 34934 // expose internals 34935 34936 this.tangents = bufferGeometry.tangents; 34937 this.normals = bufferGeometry.normals; 34938 this.binormals = bufferGeometry.binormals; 34939 34940 // create geometry 34941 34942 this.fromBufferGeometry( bufferGeometry ); 34943 this.mergeVertices(); 34944 34945 } 34946 34947 TubeGeometry.prototype = Object.create( Geometry.prototype ); 34948 TubeGeometry.prototype.constructor = TubeGeometry; 34949 34950 // TubeBufferGeometry 34951 34952 function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) { 34953 34954 BufferGeometry.call( this ); 34955 34956 this.type = 'TubeBufferGeometry'; 34957 34958 this.parameters = { 34959 path: path, 34960 tubularSegments: tubularSegments, 34961 radius: radius, 34962 radialSegments: radialSegments, 34963 closed: closed 34964 }; 34965 34966 tubularSegments = tubularSegments || 64; 34967 radius = radius || 1; 34968 radialSegments = radialSegments || 8; 34969 closed = closed || false; 34970 34971 var frames = path.computeFrenetFrames( tubularSegments, closed ); 34972 34973 // expose internals 34974 34975 this.tangents = frames.tangents; 34976 this.normals = frames.normals; 34977 this.binormals = frames.binormals; 34978 34979 // helper variables 34980 34981 var vertex = new Vector3(); 34982 var normal = new Vector3(); 34983 var uv = new Vector2(); 34984 var P = new Vector3(); 34985 34986 var i, j; 34987 34988 // buffer 34989 34990 var vertices = []; 34991 var normals = []; 34992 var uvs = []; 34993 var indices = []; 34994 34995 // create buffer data 34996 34997 generateBufferData(); 34998 34999 // build geometry 35000 35001 this.setIndex( indices ); 35002 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 35003 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 35004 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 35005 35006 // functions 35007 35008 function generateBufferData() { 35009 35010 for ( i = 0; i < tubularSegments; i ++ ) { 35011 35012 generateSegment( i ); 35013 35014 } 35015 35016 // if the geometry is not closed, generate the last row of vertices and normals 35017 // at the regular position on the given path 35018 // 35019 // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) 35020 35021 generateSegment( ( closed === false ) ? tubularSegments : 0 ); 35022 35023 // uvs are generated in a separate function. 35024 // this makes it easy compute correct values for closed geometries 35025 35026 generateUVs(); 35027 35028 // finally create faces 35029 35030 generateIndices(); 35031 35032 } 35033 35034 function generateSegment( i ) { 35035 35036 // we use getPointAt to sample evenly distributed points from the given path 35037 35038 P = path.getPointAt( i / tubularSegments, P ); 35039 35040 // retrieve corresponding normal and binormal 35041 35042 var N = frames.normals[ i ]; 35043 var B = frames.binormals[ i ]; 35044 35045 // generate normals and vertices for the current segment 35046 35047 for ( j = 0; j <= radialSegments; j ++ ) { 35048 35049 var v = j / radialSegments * Math.PI * 2; 35050 35051 var sin = Math.sin( v ); 35052 var cos = - Math.cos( v ); 35053 35054 // normal 35055 35056 normal.x = ( cos * N.x + sin * B.x ); 35057 normal.y = ( cos * N.y + sin * B.y ); 35058 normal.z = ( cos * N.z + sin * B.z ); 35059 normal.normalize(); 35060 35061 normals.push( normal.x, normal.y, normal.z ); 35062 35063 // vertex 35064 35065 vertex.x = P.x + radius * normal.x; 35066 vertex.y = P.y + radius * normal.y; 35067 vertex.z = P.z + radius * normal.z; 35068 35069 vertices.push( vertex.x, vertex.y, vertex.z ); 35070 35071 } 35072 35073 } 35074 35075 function generateIndices() { 35076 35077 for ( j = 1; j <= tubularSegments; j ++ ) { 35078 35079 for ( i = 1; i <= radialSegments; i ++ ) { 35080 35081 var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); 35082 var b = ( radialSegments + 1 ) * j + ( i - 1 ); 35083 var c = ( radialSegments + 1 ) * j + i; 35084 var d = ( radialSegments + 1 ) * ( j - 1 ) + i; 35085 35086 // faces 35087 35088 indices.push( a, b, d ); 35089 indices.push( b, c, d ); 35090 35091 } 35092 35093 } 35094 35095 } 35096 35097 function generateUVs() { 35098 35099 for ( i = 0; i <= tubularSegments; i ++ ) { 35100 35101 for ( j = 0; j <= radialSegments; j ++ ) { 35102 35103 uv.x = i / tubularSegments; 35104 uv.y = j / radialSegments; 35105 35106 uvs.push( uv.x, uv.y ); 35107 35108 } 35109 35110 } 35111 35112 } 35113 35114 } 35115 35116 TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 35117 TubeBufferGeometry.prototype.constructor = TubeBufferGeometry; 35118 35119 /** 35120 * @author oosmoxiecode 35121 * @author Mugen87 / https://github.com/Mugen87 35122 * 35123 * based on http://www.blackpawn.com/texts/pqtorus/ 35124 */ 35125 35126 // TorusKnotGeometry 35127 35128 function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) { 35129 35130 Geometry.call( this ); 35131 35132 this.type = 'TorusKnotGeometry'; 35133 35134 this.parameters = { 35135 radius: radius, 35136 tube: tube, 35137 tubularSegments: tubularSegments, 35138 radialSegments: radialSegments, 35139 p: p, 35140 q: q 35141 }; 35142 35143 if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); 35144 35145 this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); 35146 this.mergeVertices(); 35147 35148 } 35149 35150 TorusKnotGeometry.prototype = Object.create( Geometry.prototype ); 35151 TorusKnotGeometry.prototype.constructor = TorusKnotGeometry; 35152 35153 // TorusKnotBufferGeometry 35154 35155 function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) { 35156 35157 BufferGeometry.call( this ); 35158 35159 this.type = 'TorusKnotBufferGeometry'; 35160 35161 this.parameters = { 35162 radius: radius, 35163 tube: tube, 35164 tubularSegments: tubularSegments, 35165 radialSegments: radialSegments, 35166 p: p, 35167 q: q 35168 }; 35169 35170 radius = radius || 1; 35171 tube = tube || 0.4; 35172 tubularSegments = Math.floor( tubularSegments ) || 64; 35173 radialSegments = Math.floor( radialSegments ) || 8; 35174 p = p || 2; 35175 q = q || 3; 35176 35177 // buffers 35178 35179 var indices = []; 35180 var vertices = []; 35181 var normals = []; 35182 var uvs = []; 35183 35184 // helper variables 35185 35186 var i, j; 35187 35188 var vertex = new Vector3(); 35189 var normal = new Vector3(); 35190 35191 var P1 = new Vector3(); 35192 var P2 = new Vector3(); 35193 35194 var B = new Vector3(); 35195 var T = new Vector3(); 35196 var N = new Vector3(); 35197 35198 // generate vertices, normals and uvs 35199 35200 for ( i = 0; i <= tubularSegments; ++ i ) { 35201 35202 // the radian "u" is used to calculate the position on the torus curve of the current tubular segement 35203 35204 var u = i / tubularSegments * p * Math.PI * 2; 35205 35206 // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. 35207 // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions 35208 35209 calculatePositionOnCurve( u, p, q, radius, P1 ); 35210 calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); 35211 35212 // calculate orthonormal basis 35213 35214 T.subVectors( P2, P1 ); 35215 N.addVectors( P2, P1 ); 35216 B.crossVectors( T, N ); 35217 N.crossVectors( B, T ); 35218 35219 // normalize B, N. T can be ignored, we don't use it 35220 35221 B.normalize(); 35222 N.normalize(); 35223 35224 for ( j = 0; j <= radialSegments; ++ j ) { 35225 35226 // now calculate the vertices. they are nothing more than an extrusion of the torus curve. 35227 // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. 35228 35229 var v = j / radialSegments * Math.PI * 2; 35230 var cx = - tube * Math.cos( v ); 35231 var cy = tube * Math.sin( v ); 35232 35233 // now calculate the final vertex position. 35234 // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve 35235 35236 vertex.x = P1.x + ( cx * N.x + cy * B.x ); 35237 vertex.y = P1.y + ( cx * N.y + cy * B.y ); 35238 vertex.z = P1.z + ( cx * N.z + cy * B.z ); 35239 35240 vertices.push( vertex.x, vertex.y, vertex.z ); 35241 35242 // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) 35243 35244 normal.subVectors( vertex, P1 ).normalize(); 35245 35246 normals.push( normal.x, normal.y, normal.z ); 35247 35248 // uv 35249 35250 uvs.push( i / tubularSegments ); 35251 uvs.push( j / radialSegments ); 35252 35253 } 35254 35255 } 35256 35257 // generate indices 35258 35259 for ( j = 1; j <= tubularSegments; j ++ ) { 35260 35261 for ( i = 1; i <= radialSegments; i ++ ) { 35262 35263 // indices 35264 35265 var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); 35266 var b = ( radialSegments + 1 ) * j + ( i - 1 ); 35267 var c = ( radialSegments + 1 ) * j + i; 35268 var d = ( radialSegments + 1 ) * ( j - 1 ) + i; 35269 35270 // faces 35271 35272 indices.push( a, b, d ); 35273 indices.push( b, c, d ); 35274 35275 } 35276 35277 } 35278 35279 // build geometry 35280 35281 this.setIndex( indices ); 35282 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 35283 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 35284 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 35285 35286 // this function calculates the current position on the torus curve 35287 35288 function calculatePositionOnCurve( u, p, q, radius, position ) { 35289 35290 var cu = Math.cos( u ); 35291 var su = Math.sin( u ); 35292 var quOverP = q / p * u; 35293 var cs = Math.cos( quOverP ); 35294 35295 position.x = radius * ( 2 + cs ) * 0.5 * cu; 35296 position.y = radius * ( 2 + cs ) * su * 0.5; 35297 position.z = radius * Math.sin( quOverP ) * 0.5; 35298 35299 } 35300 35301 } 35302 35303 TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 35304 TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry; 35305 35306 /** 35307 * @author oosmoxiecode 35308 * @author mrdoob / http://mrdoob.com/ 35309 * @author Mugen87 / https://github.com/Mugen87 35310 */ 35311 35312 // TorusGeometry 35313 35314 function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) { 35315 35316 Geometry.call( this ); 35317 35318 this.type = 'TorusGeometry'; 35319 35320 this.parameters = { 35321 radius: radius, 35322 tube: tube, 35323 radialSegments: radialSegments, 35324 tubularSegments: tubularSegments, 35325 arc: arc 35326 }; 35327 35328 this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) ); 35329 this.mergeVertices(); 35330 35331 } 35332 35333 TorusGeometry.prototype = Object.create( Geometry.prototype ); 35334 TorusGeometry.prototype.constructor = TorusGeometry; 35335 35336 // TorusBufferGeometry 35337 35338 function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) { 35339 35340 BufferGeometry.call( this ); 35341 35342 this.type = 'TorusBufferGeometry'; 35343 35344 this.parameters = { 35345 radius: radius, 35346 tube: tube, 35347 radialSegments: radialSegments, 35348 tubularSegments: tubularSegments, 35349 arc: arc 35350 }; 35351 35352 radius = radius || 1; 35353 tube = tube || 0.4; 35354 radialSegments = Math.floor( radialSegments ) || 8; 35355 tubularSegments = Math.floor( tubularSegments ) || 6; 35356 arc = arc || Math.PI * 2; 35357 35358 // buffers 35359 35360 var indices = []; 35361 var vertices = []; 35362 var normals = []; 35363 var uvs = []; 35364 35365 // helper variables 35366 35367 var center = new Vector3(); 35368 var vertex = new Vector3(); 35369 var normal = new Vector3(); 35370 35371 var j, i; 35372 35373 // generate vertices, normals and uvs 35374 35375 for ( j = 0; j <= radialSegments; j ++ ) { 35376 35377 for ( i = 0; i <= tubularSegments; i ++ ) { 35378 35379 var u = i / tubularSegments * arc; 35380 var v = j / radialSegments * Math.PI * 2; 35381 35382 // vertex 35383 35384 vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); 35385 vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); 35386 vertex.z = tube * Math.sin( v ); 35387 35388 vertices.push( vertex.x, vertex.y, vertex.z ); 35389 35390 // normal 35391 35392 center.x = radius * Math.cos( u ); 35393 center.y = radius * Math.sin( u ); 35394 normal.subVectors( vertex, center ).normalize(); 35395 35396 normals.push( normal.x, normal.y, normal.z ); 35397 35398 // uv 35399 35400 uvs.push( i / tubularSegments ); 35401 uvs.push( j / radialSegments ); 35402 35403 } 35404 35405 } 35406 35407 // generate indices 35408 35409 for ( j = 1; j <= radialSegments; j ++ ) { 35410 35411 for ( i = 1; i <= tubularSegments; i ++ ) { 35412 35413 // indices 35414 35415 var a = ( tubularSegments + 1 ) * j + i - 1; 35416 var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; 35417 var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; 35418 var d = ( tubularSegments + 1 ) * j + i; 35419 35420 // faces 35421 35422 indices.push( a, b, d ); 35423 indices.push( b, c, d ); 35424 35425 } 35426 35427 } 35428 35429 // build geometry 35430 35431 this.setIndex( indices ); 35432 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 35433 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 35434 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 35435 35436 } 35437 35438 TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 35439 TorusBufferGeometry.prototype.constructor = TorusBufferGeometry; 35440 35441 /** 35442 * @author Mugen87 / https://github.com/Mugen87 35443 * Port from https://github.com/mapbox/earcut (v2.1.2) 35444 */ 35445 35446 var Earcut = { 35447 35448 triangulate: function ( data, holeIndices, dim ) { 35449 35450 dim = dim || 2; 35451 35452 var hasHoles = holeIndices && holeIndices.length, 35453 outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length, 35454 outerNode = linkedList( data, 0, outerLen, dim, true ), 35455 triangles = []; 35456 35457 if ( ! outerNode ) return triangles; 35458 35459 var minX, minY, maxX, maxY, x, y, invSize; 35460 35461 if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); 35462 35463 // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox 35464 35465 if ( data.length > 80 * dim ) { 35466 35467 minX = maxX = data[ 0 ]; 35468 minY = maxY = data[ 1 ]; 35469 35470 for ( var i = dim; i < outerLen; i += dim ) { 35471 35472 x = data[ i ]; 35473 y = data[ i + 1 ]; 35474 if ( x < minX ) minX = x; 35475 if ( y < minY ) minY = y; 35476 if ( x > maxX ) maxX = x; 35477 if ( y > maxY ) maxY = y; 35478 35479 } 35480 35481 // minX, minY and invSize are later used to transform coords into integers for z-order calculation 35482 35483 invSize = Math.max( maxX - minX, maxY - minY ); 35484 invSize = invSize !== 0 ? 1 / invSize : 0; 35485 35486 } 35487 35488 earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); 35489 35490 return triangles; 35491 35492 } 35493 35494 }; 35495 35496 // create a circular doubly linked list from polygon points in the specified winding order 35497 35498 function linkedList( data, start, end, dim, clockwise ) { 35499 35500 var i, last; 35501 35502 if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) { 35503 35504 for ( i = start; i < end;
vendor: 12,853 bytes, lines 35504-36132
35504 i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); 35505 35506 } else { 35507 35508 for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); 35509 35510 } 35511 35512 if ( last && equals( last, last.next ) ) { 35513 35514 removeNode( last ); 35515 last = last.next; 35516 35517 } 35518 35519 return last; 35520 35521 } 35522 35523 // eliminate colinear or duplicate points 35524 35525 function filterPoints( start, end ) { 35526 35527 if ( ! start ) return start; 35528 if ( ! end ) end = start; 35529 35530 var p = start, again; 35531 35532 do { 35533 35534 again = false; 35535 35536 if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { 35537 35538 removeNode( p ); 35539 p = end = p.prev; 35540 if ( p === p.next ) break; 35541 again = true; 35542 35543 } else { 35544 35545 p = p.next; 35546 35547 } 35548 35549 } while ( again || p !== end ); 35550 35551 return end; 35552 35553 } 35554 35555 // main ear slicing loop which triangulates a polygon (given as a linked list) 35556 35557 function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { 35558 35559 if ( ! ear ) return; 35560 35561 // interlink polygon nodes in z-order 35562 35563 if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); 35564 35565 var stop = ear, prev, next; 35566 35567 // iterate through ears, slicing them one by one 35568 35569 while ( ear.prev !== ear.next ) { 35570 35571 prev = ear.prev; 35572 next = ear.next; 35573 35574 if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) { 35575 35576 // cut off the triangle 35577 triangles.push( prev.i / dim ); 35578 triangles.push( ear.i / dim ); 35579 triangles.push( next.i / dim ); 35580 35581 removeNode( ear ); 35582 35583 // skipping the next vertice leads to less sliver triangles 35584 ear = next.next; 35585 stop = next.next; 35586 35587 continue; 35588 35589 } 35590 35591 ear = next; 35592 35593 // if we looped through the whole remaining polygon and can't find any more ears 35594 35595 if ( ear === stop ) { 35596 35597 // try filtering points and slicing again 35598 35599 if ( ! pass ) { 35600 35601 earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 ); 35602 35603 // if this didn't work, try curing all small self-intersections locally 35604 35605 } else if ( pass === 1 ) { 35606 35607 ear = cureLocalIntersections( ear, triangles, dim ); 35608 earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); 35609 35610 // as a last resort, try splitting the remaining polygon into two 35611 35612 } else if ( pass === 2 ) { 35613 35614 splitEarcut( ear, triangles, dim, minX, minY, invSize ); 35615 35616 } 35617 35618 break; 35619 35620 } 35621 35622 } 35623 35624 } 35625 35626 // check whether a polygon node forms a valid ear with adjacent nodes 35627 35628 function isEar( ear ) { 35629 35630 var a = ear.prev, 35631 b = ear, 35632 c = ear.next; 35633 35634 if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear 35635 35636 // now make sure we don't have other points inside the potential ear 35637 var p = ear.next.next; 35638 35639 while ( p !== ear.prev ) { 35640 35641 if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) { 35642 35643 return false; 35644 35645 } 35646 35647 p = p.next; 35648 35649 } 35650 35651 return true; 35652 35653 } 35654 35655 function isEarHashed( ear, minX, minY, invSize ) { 35656 35657 var a = ear.prev, 35658 b = ear, 35659 c = ear.next; 35660 35661 if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear 35662 35663 // triangle bbox; min & max are calculated like this for speed 35664 35665 var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), 35666 minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ), 35667 maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ), 35668 maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y ); 35669 35670 // z-order range for the current triangle bbox; 35671 35672 var minZ = zOrder( minTX, minTY, minX, minY, invSize ), 35673 maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); 35674 35675 // first look for points inside the triangle in increasing z-order 35676 35677 var p = ear.nextZ; 35678 35679 while ( p && p.z <= maxZ ) { 35680 35681 if ( p !== ear.prev && p !== ear.next && 35682 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && 35683 area( p.prev, p, p.next ) >= 0 ) return false; 35684 p = p.nextZ; 35685 35686 } 35687 35688 // then look for points in decreasing z-order 35689 35690 p = ear.prevZ; 35691 35692 while ( p && p.z >= minZ ) { 35693 35694 if ( p !== ear.prev && p !== ear.next && 35695 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && 35696 area( p.prev, p, p.next ) >= 0 ) return false; 35697 35698 p = p.prevZ; 35699 35700 } 35701 35702 return true; 35703 35704 } 35705 35706 // go through all polygon nodes and cure small local self-intersections 35707 35708 function cureLocalIntersections( start, triangles, dim ) { 35709 35710 var p = start; 35711 35712 do { 35713 35714 var a = p.prev, b = p.next.next; 35715 35716 if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) { 35717 35718 triangles.push( a.i / dim ); 35719 triangles.push( p.i / dim ); 35720 triangles.push( b.i / dim ); 35721 35722 // remove two nodes involved 35723 35724 removeNode( p ); 35725 removeNode( p.next ); 35726 35727 p = start = b; 35728 35729 } 35730 35731 p = p.next; 35732 35733 } while ( p !== start ); 35734 35735 return p; 35736 35737 } 35738 35739 // try splitting polygon into two and triangulate them independently 35740 35741 function splitEarcut( start, triangles, dim, minX, minY, invSize ) { 35742 35743 // look for a valid diagonal that divides the polygon into two 35744 35745 var a = start; 35746 35747 do { 35748 35749 var b = a.next.next; 35750 35751 while ( b !== a.prev ) { 35752 35753 if ( a.i !== b.i && isValidDiagonal( a, b ) ) { 35754 35755 // split the polygon in two by the diagonal 35756 35757 var c = splitPolygon( a, b ); 35758 35759 // filter colinear points around the cuts 35760 35761 a = filterPoints( a, a.next ); 35762 c = filterPoints( c, c.next ); 35763 35764 // run earcut on each half 35765 35766 earcutLinked( a, triangles, dim, minX, minY, invSize ); 35767 earcutLinked( c, triangles, dim, minX, minY, invSize ); 35768 return; 35769 35770 } 35771 35772 b = b.next; 35773 35774 } 35775 35776 a = a.next; 35777 35778 } while ( a !== start ); 35779 35780 } 35781 35782 // link every hole into the outer loop, producing a single-ring polygon without holes 35783 35784 function eliminateHoles( data, holeIndices, outerNode, dim ) { 35785 35786 var queue = [], i, len, start, end, list; 35787 35788 for ( i = 0, len = holeIndices.length; i < len; i ++ ) { 35789 35790 start = holeIndices[ i ] * dim; 35791 end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length; 35792 list = linkedList( data, start, end, dim, false ); 35793 if ( list === list.next ) list.steiner = true; 35794 queue.push( getLeftmost( list ) ); 35795 35796 } 35797 35798 queue.sort( compareX ); 35799 35800 // process holes from left to right 35801 35802 for ( i = 0; i < queue.length; i ++ ) { 35803 35804 eliminateHole( queue[ i ], outerNode ); 35805 outerNode = filterPoints( outerNode, outerNode.next ); 35806 35807 } 35808 35809 return outerNode; 35810 35811 } 35812 35813 function compareX( a, b ) { 35814 35815 return a.x - b.x; 35816 35817 } 35818 35819 // find a bridge between vertices that connects hole with an outer ring and and link it 35820 35821 function eliminateHole( hole, outerNode ) { 35822 35823 outerNode = findHoleBridge( hole, outerNode ); 35824 35825 if ( outerNode ) { 35826 35827 var b = splitPolygon( outerNode, hole ); 35828 35829 filterPoints( b, b.next ); 35830 35831 } 35832 35833 } 35834 35835 // David Eberly's algorithm for finding a bridge between hole and outer polygon 35836 35837 function findHoleBridge( hole, outerNode ) { 35838 35839 var p = outerNode, 35840 hx = hole.x, 35841 hy = hole.y, 35842 qx = - Infinity, 35843 m; 35844 35845 // find a segment intersected by a ray from the hole's leftmost point to the left; 35846 // segment's endpoint with lesser x will be potential connection point 35847 35848 do { 35849 35850 if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) { 35851 35852 var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y ); 35853 35854 if ( x <= hx && x > qx ) { 35855 35856 qx = x; 35857 35858 if ( x === hx ) { 35859 35860 if ( hy === p.y ) return p; 35861 if ( hy === p.next.y ) return p.next; 35862 35863 } 35864 35865 m = p.x < p.next.x ? p : p.next; 35866 35867 } 35868 35869 } 35870 35871 p = p.next; 35872 35873 } while ( p !== outerNode ); 35874 35875 if ( ! m ) return null; 35876 35877 if ( hx === qx ) return m.prev; // hole touches outer segment; pick lower endpoint 35878 35879 // look for points inside the triangle of hole point, segment intersection and endpoint; 35880 // if there are no points found, we have a valid connection; 35881 // otherwise choose the point of the minimum angle with the ray as connection point 35882 35883 var stop = m, 35884 mx = m.x, 35885 my = m.y, 35886 tanMin = Infinity, 35887 tan; 35888 35889 p = m.next; 35890 35891 while ( p !== stop ) { 35892 35893 if ( hx >= p.x && p.x >= mx && hx !== p.x && 35894 pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { 35895 35896 tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential 35897 35898 if ( ( tan < tanMin || ( tan === tanMin && p.x > m.x ) ) && locallyInside( p, hole ) ) { 35899 35900 m = p; 35901 tanMin = tan; 35902 35903 } 35904 35905 } 35906 35907 p = p.next; 35908 35909 } 35910 35911 return m; 35912 35913 } 35914 35915 // interlink polygon nodes in z-order 35916 35917 function indexCurve( start, minX, minY, invSize ) { 35918 35919 var p = start; 35920 35921 do { 35922 35923 if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); 35924 p.prevZ = p.prev; 35925 p.nextZ = p.next; 35926 p = p.next; 35927 35928 } while ( p !== start ); 35929 35930 p.prevZ.nextZ = null; 35931 p.prevZ = null; 35932 35933 sortLinked( p ); 35934 35935 } 35936 35937 // Simon Tatham's linked list merge sort algorithm 35938 // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html 35939 35940 function sortLinked( list ) { 35941 35942 var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; 35943 35944 do { 35945 35946 p = list; 35947 list = null; 35948 tail = null; 35949 numMerges = 0; 35950 35951 while ( p ) { 35952 35953 numMerges ++; 35954 q = p; 35955 pSize = 0; 35956 35957 for ( i = 0; i < inSize; i ++ ) { 35958 35959 pSize ++; 35960 q = q.nextZ; 35961 if ( ! q ) break; 35962 35963 } 35964 35965 qSize = inSize; 35966 35967 while ( pSize > 0 || ( qSize > 0 && q ) ) { 35968 35969 if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) { 35970 35971 e = p; 35972 p = p.nextZ; 35973 pSize --; 35974 35975 } else { 35976 35977 e = q; 35978 q = q.nextZ; 35979 qSize --; 35980 35981 } 35982 35983 if ( tail ) tail.nextZ = e; 35984 else list = e; 35985 35986 e.prevZ = tail; 35987 tail = e; 35988 35989 } 35990 35991 p = q; 35992 35993 } 35994 35995 tail.nextZ = null; 35996 inSize *= 2; 35997 35998 } while ( numMerges > 1 ); 35999 36000 return list; 36001 36002 } 36003 36004 // z-order of a point given coords and inverse of the longer side of data bbox 36005 36006 function zOrder( x, y, minX, minY, invSize ) { 36007 36008 // coords are transformed into non-negative 15-bit integer range 36009 36010 x = 32767 * ( x - minX ) * invSize; 36011 y = 32767 * ( y - minY ) * invSize; 36012 36013 x = ( x | ( x << 8 ) ) & 0x00FF00FF; 36014 x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; 36015 x = ( x | ( x << 2 ) ) & 0x33333333; 36016 x = ( x | ( x << 1 ) ) & 0x55555555; 36017 36018 y = ( y | ( y << 8 ) ) & 0x00FF00FF; 36019 y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; 36020 y = ( y | ( y << 2 ) ) & 0x33333333; 36021 y = ( y | ( y << 1 ) ) & 0x55555555; 36022 36023 return x | ( y << 1 ); 36024 36025 } 36026 36027 // find the leftmost node of a polygon ring 36028 36029 function getLeftmost( start ) { 36030 36031 var p = start, leftmost = start; 36032 36033 do { 36034 36035 if ( p.x < leftmost.x ) leftmost = p; 36036 p = p.next; 36037 36038 } while ( p !== start ); 36039 36040 return leftmost; 36041 36042 } 36043 36044 // check if a point lies within a convex triangle 36045 36046 function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) { 36047 36048 return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 && 36049 ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && 36050 ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; 36051 36052 } 36053 36054 // check if a diagonal between two polygon nodes is valid (lies in polygon interior) 36055 36056 function isValidDiagonal( a, b ) { 36057 36058 return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && 36059 locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ); 36060 36061 } 36062 36063 // signed area of a triangle 36064 36065 function area( p, q, r ) { 36066 36067 return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y ); 36068 36069 } 36070 36071 // check if two points are equal 36072 36073 function equals( p1, p2 ) { 36074 36075 return p1.x === p2.x && p1.y === p2.y; 36076 36077 } 36078 36079 // check if two segments intersect 36080 36081 function intersects( p1, q1, p2, q2 ) { 36082 36083 if ( ( equals( p1, q1 ) && equals( p2, q2 ) ) || 36084 ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; 36085 36086 return area( p1, q1, p2 ) > 0 !== area( p1, q1, q2 ) > 0 && 36087 area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; 36088 36089 } 36090 36091 // check if a polygon diagonal intersects any polygon segments 36092 36093 function intersectsPolygon( a, b ) { 36094 36095 var p = a; 36096 36097 do { 36098 36099 if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && 36100 intersects( p, p.next, a, b ) ) { 36101 36102 return true; 36103 36104 } 36105 36106 p = p.next; 36107 36108 } while ( p !== a ); 36109 36110 return false; 36111 36112 } 36113 36114 // check if a polygon diagonal is locally inside the polygon 36115 36116 function locallyInside( a, b ) { 36117 36118 return area( a.prev, a, a.next ) < 0 ? 36119 area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 : 36120 area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0; 36121 36122 } 36123 36124 // check if the middle point of a polygon diagonal is inside the polygon 36125 36126 function middleInside( a, b ) { 36127 36128 var p = a, 36129 inside = false, 36130 px = ( a.x + b.x ) / 2, 36131 py = ( a.y + b.y ) / 2; 36132
vendor: 56,222 bytes, lines 36133-38626
36133 do { 36134 36135 if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && 36136 ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) { 36137 36138 inside = ! inside; 36139 36140 } 36141 36142 p = p.next; 36143 36144 } while ( p !== a ); 36145 36146 return inside; 36147 36148 } 36149 36150 // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; 36151 // if one belongs to the outer ring and another to a hole, it merges it into a single ring 36152 36153 function splitPolygon( a, b ) { 36154 36155 var a2 = new Node( a.i, a.x, a.y ), 36156 b2 = new Node( b.i, b.x, b.y ), 36157 an = a.next, 36158 bp = b.prev; 36159 36160 a.next = b; 36161 b.prev = a; 36162 36163 a2.next = an; 36164 an.prev = a2; 36165 36166 b2.next = a2; 36167 a2.prev = b2; 36168 36169 bp.next = b2; 36170 b2.prev = bp; 36171 36172 return b2; 36173 36174 } 36175 36176 // create a node and optionally link it with previous one (in a circular doubly linked list) 36177 36178 function insertNode( i, x, y, last ) { 36179 36180 var p = new Node( i, x, y ); 36181 36182 if ( ! last ) { 36183 36184 p.prev = p; 36185 p.next = p; 36186 36187 } else { 36188 36189 p.next = last.next; 36190 p.prev = last; 36191 last.next.prev = p; 36192 last.next = p; 36193 36194 } 36195 36196 return p; 36197 36198 } 36199 36200 function removeNode( p ) { 36201 36202 p.next.prev = p.prev; 36203 p.prev.next = p.next; 36204 36205 if ( p.prevZ ) p.prevZ.nextZ = p.nextZ; 36206 if ( p.nextZ ) p.nextZ.prevZ = p.prevZ; 36207 36208 } 36209 36210 function Node( i, x, y ) { 36211 36212 // vertice index in coordinates array 36213 this.i = i; 36214 36215 // vertex coordinates 36216 this.x = x; 36217 this.y = y; 36218 36219 // previous and next vertice nodes in a polygon ring 36220 this.prev = null; 36221 this.next = null; 36222 36223 // z-order curve value 36224 this.z = null; 36225 36226 // previous and next nodes in z-order 36227 this.prevZ = null; 36228 this.nextZ = null; 36229 36230 // indicates whether this is a steiner point 36231 this.steiner = false; 36232 36233 } 36234 36235 function signedArea( data, start, end, dim ) { 36236 36237 var sum = 0; 36238 36239 for ( var i = start, j = end - dim; i < end; i += dim ) { 36240 36241 sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] ); 36242 j = i; 36243 36244 } 36245 36246 return sum; 36247 36248 } 36249 36250 /** 36251 * @author zz85 / http://www.lab4games.net/zz85/blog 36252 */ 36253 36254 var ShapeUtils = { 36255 36256 // calculate area of the contour polygon 36257 36258 area: function ( contour ) { 36259 36260 var n = contour.length; 36261 var a = 0.0; 36262 36263 for ( var p = n - 1, q = 0; q < n; p = q ++ ) { 36264 36265 a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y; 36266 36267 } 36268 36269 return a * 0.5; 36270 36271 }, 36272 36273 isClockWise: function ( pts ) { 36274 36275 return ShapeUtils.area( pts ) < 0; 36276 36277 }, 36278 36279 triangulateShape: function ( contour, holes ) { 36280 36281 var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] 36282 var holeIndices = []; // array of hole indices 36283 var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] 36284 36285 removeDupEndPts( contour ); 36286 addContour( vertices, contour ); 36287 36288 // 36289 36290 var holeIndex = contour.length; 36291 36292 holes.forEach( removeDupEndPts ); 36293 36294 for ( var i = 0; i < holes.length; i ++ ) { 36295 36296 holeIndices.push( holeIndex ); 36297 holeIndex += holes[ i ].length; 36298 addContour( vertices, holes[ i ] ); 36299 36300 } 36301 36302 // 36303 36304 var triangles = Earcut.triangulate( vertices, holeIndices ); 36305 36306 // 36307 36308 for ( var i = 0; i < triangles.length; i += 3 ) { 36309 36310 faces.push( triangles.slice( i, i + 3 ) ); 36311 36312 } 36313 36314 return faces; 36315 36316 } 36317 36318 }; 36319 36320 function removeDupEndPts( points ) { 36321 36322 var l = points.length; 36323 36324 if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) { 36325 36326 points.pop(); 36327 36328 } 36329 36330 } 36331 36332 function addContour( vertices, contour ) { 36333 36334 for ( var i = 0; i < contour.length; i ++ ) { 36335 36336 vertices.push( contour[ i ].x ); 36337 vertices.push( contour[ i ].y ); 36338 36339 } 36340 36341 } 36342 36343 /** 36344 * @author zz85 / http://www.lab4games.net/zz85/blog 36345 * 36346 * Creates extruded geometry from a path shape. 36347 * 36348 * parameters = { 36349 * 36350 * curveSegments: <int>, // number of points on the curves 36351 * steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too 36352 * depth: <float>, // Depth to extrude the shape 36353 * 36354 * bevelEnabled: <bool>, // turn on bevel 36355 * bevelThickness: <float>, // how deep into the original shape bevel goes 36356 * bevelSize: <float>, // how far from shape outline is bevel 36357 * bevelSegments: <int>, // number of bevel layers 36358 * 36359 * extrudePath: <THREE.Curve> // curve to extrude shape along 36360 * 36361 * UVGenerator: <Object> // object that provides UV generator functions 36362 * 36363 * } 36364 */ 36365 36366 // ExtrudeGeometry 36367 36368 function ExtrudeGeometry( shapes, options ) { 36369 36370 Geometry.call( this ); 36371 36372 this.type = 'ExtrudeGeometry'; 36373 36374 this.parameters = { 36375 shapes: shapes, 36376 options: options 36377 }; 36378 36379 this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) ); 36380 this.mergeVertices(); 36381 36382 } 36383 36384 ExtrudeGeometry.prototype = Object.create( Geometry.prototype ); 36385 ExtrudeGeometry.prototype.constructor = ExtrudeGeometry; 36386 36387 ExtrudeGeometry.prototype.toJSON = function () { 36388 36389 var data = Geometry.prototype.toJSON.call( this ); 36390 36391 var shapes = this.parameters.shapes; 36392 var options = this.parameters.options; 36393 36394 return toJSON( shapes, options, data ); 36395 36396 }; 36397 36398 // ExtrudeBufferGeometry 36399 36400 function ExtrudeBufferGeometry( shapes, options ) { 36401 36402 BufferGeometry.call( this ); 36403 36404 this.type = 'ExtrudeBufferGeometry'; 36405 36406 this.parameters = { 36407 shapes: shapes, 36408 options: options 36409 }; 36410 36411 shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; 36412 36413 var scope = this; 36414 36415 var verticesArray = []; 36416 var uvArray = []; 36417 36418 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 36419 36420 var shape = shapes[ i ]; 36421 addShape( shape ); 36422 36423 } 36424 36425 // build geometry 36426 36427 this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); 36428 this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); 36429 36430 this.computeVertexNormals(); 36431 36432 // functions 36433 36434 function addShape( shape ) { 36435 36436 var placeholder = []; 36437 36438 // options 36439 36440 var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; 36441 var steps = options.steps !== undefined ? options.steps : 1; 36442 var depth = options.depth !== undefined ? options.depth : 100; 36443 36444 var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; 36445 var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; 36446 var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; 36447 var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; 36448 36449 var extrudePath = options.extrudePath; 36450 36451 var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; 36452 36453 // deprecated options 36454 36455 if ( options.amount !== undefined ) { 36456 36457 console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); 36458 depth = options.amount; 36459 36460 } 36461 36462 // 36463 36464 var extrudePts, extrudeByPath = false; 36465 var splineTube, binormal, normal, position2; 36466 36467 if ( extrudePath ) { 36468 36469 extrudePts = extrudePath.getSpacedPoints( steps ); 36470 36471 extrudeByPath = true; 36472 bevelEnabled = false; // bevels not supported for path extrusion 36473 36474 // SETUP TNB variables 36475 36476 // TODO1 - have a .isClosed in spline? 36477 36478 splineTube = extrudePath.computeFrenetFrames( steps, false ); 36479 36480 // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); 36481 36482 binormal = new Vector3(); 36483 normal = new Vector3(); 36484 position2 = new Vector3(); 36485 36486 } 36487 36488 // Safeguards if bevels are not enabled 36489 36490 if ( ! bevelEnabled ) { 36491 36492 bevelSegments = 0; 36493 bevelThickness = 0; 36494 bevelSize = 0; 36495 36496 } 36497 36498 // Variables initialization 36499 36500 var ahole, h, hl; // looping of holes 36501 36502 var shapePoints = shape.extractPoints( curveSegments ); 36503 36504 var vertices = shapePoints.shape; 36505 var holes = shapePoints.holes; 36506 36507 var reverse = ! ShapeUtils.isClockWise( vertices ); 36508 36509 if ( reverse ) { 36510 36511 vertices = vertices.reverse(); 36512 36513 // Maybe we should also check if holes are in the opposite direction, just to be safe ... 36514 36515 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36516 36517 ahole = holes[ h ]; 36518 36519 if ( ShapeUtils.isClockWise( ahole ) ) { 36520 36521 holes[ h ] = ahole.reverse(); 36522 36523 } 36524 36525 } 36526 36527 } 36528 36529 36530 var faces = ShapeUtils.triangulateShape( vertices, holes ); 36531 36532 /* Vertices */ 36533 36534 var contour = vertices; // vertices has all points but contour has only points of circumference 36535 36536 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36537 36538 ahole = holes[ h ]; 36539 36540 vertices = vertices.concat( ahole ); 36541 36542 } 36543 36544 36545 function scalePt2( pt, vec, size ) { 36546 36547 if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" ); 36548 36549 return vec.clone().multiplyScalar( size ).add( pt ); 36550 36551 } 36552 36553 var b, bs, t, z, 36554 vert, vlen = vertices.length, 36555 face, flen = faces.length; 36556 36557 36558 // Find directions for point movement 36559 36560 36561 function getBevelVec( inPt, inPrev, inNext ) { 36562 36563 // computes for inPt the corresponding point inPt' on a new contour 36564 // shifted by 1 unit (length of normalized vector) to the left 36565 // if we walk along contour clockwise, this new contour is outside the old one 36566 // 36567 // inPt' is the intersection of the two lines parallel to the two 36568 // adjacent edges of inPt at a distance of 1 unit on the left side. 36569 36570 var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt 36571 36572 // good reading for geometry algorithms (here: line-line intersection) 36573 // http://geomalgorithms.com/a05-_intersect-1.html 36574 36575 var v_prev_x = inPt.x - inPrev.x, 36576 v_prev_y = inPt.y - inPrev.y; 36577 var v_next_x = inNext.x - inPt.x, 36578 v_next_y = inNext.y - inPt.y; 36579 36580 var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); 36581 36582 // check for collinear edges 36583 var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); 36584 36585 if ( Math.abs( collinear0 ) > Number.EPSILON ) { 36586 36587 // not collinear 36588 36589 // length of vectors for normalizing 36590 36591 var v_prev_len = Math.sqrt( v_prev_lensq ); 36592 var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); 36593 36594 // shift adjacent points by unit vectors to the left 36595 36596 var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); 36597 var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); 36598 36599 var ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); 36600 var ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); 36601 36602 // scaling factor for v_prev to intersection point 36603 36604 var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - 36605 ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / 36606 ( v_prev_x * v_next_y - v_prev_y * v_next_x ); 36607 36608 // vector from inPt to intersection point 36609 36610 v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); 36611 v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); 36612 36613 // Don't normalize!, otherwise sharp corners become ugly 36614 // but prevent crazy spikes 36615 var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ); 36616 if ( v_trans_lensq <= 2 ) { 36617 36618 return new Vector2( v_trans_x, v_trans_y ); 36619 36620 } else { 36621 36622 shrink_by = Math.sqrt( v_trans_lensq / 2 ); 36623 36624 } 36625 36626 } else { 36627 36628 // handle special case of collinear edges 36629 36630 var direction_eq = false; // assumes: opposite 36631 if ( v_prev_x > Number.EPSILON ) { 36632 36633 if ( v_next_x > Number.EPSILON ) { 36634 36635 direction_eq = true; 36636 36637 } 36638 36639 } else { 36640 36641 if ( v_prev_x < - Number.EPSILON ) { 36642 36643 if ( v_next_x < - Number.EPSILON ) { 36644 36645 direction_eq = true; 36646 36647 } 36648 36649 } else { 36650 36651 if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { 36652 36653 direction_eq = true; 36654 36655 } 36656 36657 } 36658 36659 } 36660 36661 if ( direction_eq ) { 36662 36663 // console.log("Warning: lines are a straight sequence"); 36664 v_trans_x = - v_prev_y; 36665 v_trans_y = v_prev_x; 36666 shrink_by = Math.sqrt( v_prev_lensq ); 36667 36668 } else { 36669 36670 // console.log("Warning: lines are a straight spike"); 36671 v_trans_x = v_prev_x; 36672 v_trans_y = v_prev_y; 36673 shrink_by = Math.sqrt( v_prev_lensq / 2 ); 36674 36675 } 36676 36677 } 36678 36679 return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); 36680 36681 } 36682 36683 36684 var contourMovements = []; 36685 36686 for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { 36687 36688 if ( j === il ) j = 0; 36689 if ( k === il ) k = 0; 36690 36691 // (j)---(i)---(k) 36692 // console.log('i,j,k', i, j , k) 36693 36694 contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); 36695 36696 } 36697 36698 var holesMovements = [], 36699 oneHoleMovements, verticesMovements = contourMovements.concat(); 36700 36701 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36702 36703 ahole = holes[ h ]; 36704 36705 oneHoleMovements = []; 36706 36707 for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { 36708 36709 if ( j === il ) j = 0; 36710 if ( k === il ) k = 0; 36711 36712 // (j)---(i)---(k) 36713 oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); 36714 36715 } 36716 36717 holesMovements.push( oneHoleMovements ); 36718 verticesMovements = verticesMovements.concat( oneHoleMovements ); 36719 36720 } 36721 36722 36723 // Loop bevelSegments, 1 for the front, 1 for the back 36724 36725 for ( b = 0; b < bevelSegments; b ++ ) { 36726 36727 //for ( b = bevelSegments; b > 0; b -- ) { 36728 36729 t = b / bevelSegments; 36730 z = bevelThickness * Math.cos( t * Math.PI / 2 ); 36731 bs = bevelSize * Math.sin( t * Math.PI / 2 ); 36732 36733 // contract shape 36734 36735 for ( i = 0, il = contour.length; i < il; i ++ ) { 36736 36737 vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); 36738 36739 v( vert.x, vert.y, - z ); 36740 36741 } 36742 36743 // expand holes 36744 36745 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36746 36747 ahole = holes[ h ]; 36748 oneHoleMovements = holesMovements[ h ]; 36749 36750 for ( i = 0, il = ahole.length; i < il; i ++ ) { 36751 36752 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); 36753 36754 v( vert.x, vert.y, - z ); 36755 36756 } 36757 36758 } 36759 36760 } 36761 36762 bs = bevelSize; 36763 36764 // Back facing vertices 36765 36766 for ( i = 0; i < vlen; i ++ ) { 36767 36768 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; 36769 36770 if ( ! extrudeByPath ) { 36771 36772 v( vert.x, vert.y, 0 ); 36773 36774 } else { 36775 36776 // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); 36777 36778 normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x ); 36779 binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y ); 36780 36781 position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal ); 36782 36783 v( position2.x, position2.y, position2.z ); 36784 36785 } 36786 36787 } 36788 36789 // Add stepped vertices... 36790 // Including front facing vertices 36791 36792 var s; 36793 36794 for ( s = 1; s <= steps; s ++ ) { 36795 36796 for ( i = 0; i < vlen; i ++ ) { 36797 36798 vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; 36799 36800 if ( ! extrudeByPath ) { 36801 36802 v( vert.x, vert.y, depth / steps * s ); 36803 36804 } else { 36805 36806 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); 36807 36808 normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x ); 36809 binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y ); 36810 36811 position2.copy( extrudePts[ s ] ).add( normal ).add( binormal ); 36812 36813 v( position2.x, position2.y, position2.z ); 36814 36815 } 36816 36817 } 36818 36819 } 36820 36821 36822 // Add bevel segments planes 36823 36824 //for ( b = 1; b <= bevelSegments; b ++ ) { 36825 for ( b = bevelSegments - 1; b >= 0; b -- ) { 36826 36827 t = b / bevelSegments; 36828 z = bevelThickness * Math.cos( t * Math.PI / 2 ); 36829 bs = bevelSize * Math.sin( t * Math.PI / 2 ); 36830 36831 // contract shape 36832 36833 for ( i = 0, il = contour.length; i < il; i ++ ) { 36834 36835 vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); 36836 v( vert.x, vert.y, depth + z ); 36837 36838 } 36839 36840 // expand holes 36841 36842 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36843 36844 ahole = holes[ h ]; 36845 oneHoleMovements = holesMovements[ h ]; 36846 36847 for ( i = 0, il = ahole.length; i < il; i ++ ) { 36848 36849 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); 36850 36851 if ( ! extrudeByPath ) { 36852 36853 v( vert.x, vert.y, depth + z ); 36854 36855 } else { 36856 36857 v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); 36858 36859 } 36860 36861 } 36862 36863 } 36864 36865 } 36866 36867 /* Faces */ 36868 36869 // Top and bottom faces 36870 36871 buildLidFaces(); 36872 36873 // Sides faces 36874 36875 buildSideFaces(); 36876 36877 36878 ///// Internal functions 36879 36880 function buildLidFaces() { 36881 36882 var start = verticesArray.length / 3; 36883 36884 if ( bevelEnabled ) { 36885 36886 var layer = 0; // steps + 1 36887 var offset = vlen * layer; 36888 36889 // Bottom faces 36890 36891 for ( i = 0; i < flen; i ++ ) { 36892 36893 face = faces[ i ]; 36894 f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); 36895 36896 } 36897 36898 layer = steps + bevelSegments * 2; 36899 offset = vlen * layer; 36900 36901 // Top faces 36902 36903 for ( i = 0; i < flen; i ++ ) { 36904 36905 face = faces[ i ]; 36906 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); 36907 36908 } 36909 36910 } else { 36911 36912 // Bottom faces 36913 36914 for ( i = 0; i < flen; i ++ ) { 36915 36916 face = faces[ i ]; 36917 f3( face[ 2 ], face[ 1 ], face[ 0 ] ); 36918 36919 } 36920 36921 // Top faces 36922 36923 for ( i = 0; i < flen; i ++ ) { 36924 36925 face = faces[ i ]; 36926 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps ); 36927 36928 } 36929 36930 } 36931 36932 scope.addGroup( start, verticesArray.length / 3 - start, 0 ); 36933 36934 } 36935 36936 // Create faces for the z-sides of the shape 36937 36938 function buildSideFaces() { 36939 36940 var start = verticesArray.length / 3; 36941 var layeroffset = 0; 36942 sidewalls( contour, layeroffset ); 36943 layeroffset += contour.length; 36944 36945 for ( h = 0, hl = holes.length; h < hl; h ++ ) { 36946 36947 ahole = holes[ h ]; 36948 sidewalls( ahole, layeroffset ); 36949 36950 //, true 36951 layeroffset += ahole.length; 36952 36953 } 36954 36955 36956 scope.addGroup( start, verticesArray.length / 3 - start, 1 ); 36957 36958 36959 } 36960 36961 function sidewalls( contour, layeroffset ) { 36962 36963 var j, k; 36964 i = contour.length; 36965 36966 while ( -- i >= 0 ) { 36967 36968 j = i; 36969 k = i - 1; 36970 if ( k < 0 ) k = contour.length - 1; 36971 36972 //console.log('b', i,j, i-1, k,vertices.length); 36973 36974 var s = 0, 36975 sl = steps + bevelSegments * 2; 36976 36977 for ( s = 0; s < sl; s ++ ) { 36978 36979 var slen1 = vlen * s; 36980 var slen2 = vlen * ( s + 1 ); 36981 36982 var a = layeroffset + j + slen1, 36983 b = layeroffset + k + slen1, 36984 c = layeroffset + k + slen2, 36985 d = layeroffset + j + slen2; 36986 36987 f4( a, b, c, d ); 36988 36989 } 36990 36991 } 36992 36993 } 36994 36995 function v( x, y, z ) { 36996 36997 placeholder.push( x ); 36998 placeholder.push( y ); 36999 placeholder.push( z ); 37000 37001 } 37002 37003 37004 function f3( a, b, c ) { 37005 37006 addVertex( a ); 37007 addVertex( b ); 37008 addVertex( c ); 37009 37010 var nextIndex = verticesArray.length / 3; 37011 var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); 37012 37013 addUV( uvs[ 0 ] ); 37014 addUV( uvs[ 1 ] ); 37015 addUV( uvs[ 2 ] ); 37016 37017 } 37018 37019 function f4( a, b, c, d ) { 37020 37021 addVertex( a ); 37022 addVertex( b ); 37023 addVertex( d ); 37024 37025 addVertex( b ); 37026 addVertex( c ); 37027 addVertex( d ); 37028 37029 37030 var nextIndex = verticesArray.length / 3; 37031 var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); 37032 37033 addUV( uvs[ 0 ] ); 37034 addUV( uvs[ 1 ] ); 37035 addUV( uvs[ 3 ] ); 37036 37037 addUV( uvs[ 1 ] ); 37038 addUV( uvs[ 2 ] ); 37039 addUV( uvs[ 3 ] ); 37040 37041 } 37042 37043 function addVertex( index ) { 37044 37045 verticesArray.push( placeholder[ index * 3 + 0 ] ); 37046 verticesArray.push( placeholder[ index * 3 + 1 ] ); 37047 verticesArray.push( placeholder[ index * 3 + 2 ] ); 37048 37049 } 37050 37051 37052 function addUV( vector2 ) { 37053 37054 uvArray.push( vector2.x ); 37055 uvArray.push( vector2.y ); 37056 37057 } 37058 37059 } 37060 37061 } 37062 37063 ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 37064 ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry; 37065 37066 ExtrudeBufferGeometry.prototype.toJSON = function () { 37067 37068 var data = BufferGeometry.prototype.toJSON.call( this ); 37069 37070 var shapes = this.parameters.shapes; 37071 var options = this.parameters.options; 37072 37073 return toJSON( shapes, options, data ); 37074 37075 }; 37076 37077 // 37078 37079 var WorldUVGenerator = { 37080 37081 generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) { 37082 37083 var a_x = vertices[ indexA * 3 ]; 37084 var a_y = vertices[ indexA * 3 + 1 ]; 37085 var b_x = vertices[ indexB * 3 ]; 37086 var b_y = vertices[ indexB * 3 + 1 ]; 37087 var c_x = vertices[ indexC * 3 ]; 37088 var c_y = vertices[ indexC * 3 + 1 ]; 37089 37090 return [ 37091 new Vector2( a_x, a_y ), 37092 new Vector2( b_x, b_y ), 37093 new Vector2( c_x, c_y ) 37094 ]; 37095 37096 }, 37097 37098 generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { 37099 37100 var a_x = vertices[ indexA * 3 ]; 37101 var a_y = vertices[ indexA * 3 + 1 ]; 37102 var a_z = vertices[ indexA * 3 + 2 ]; 37103 var b_x = vertices[ indexB * 3 ]; 37104 var b_y = vertices[ indexB * 3 + 1 ]; 37105 var b_z = vertices[ indexB * 3 + 2 ]; 37106 var c_x = vertices[ indexC * 3 ]; 37107 var c_y = vertices[ indexC * 3 + 1 ]; 37108 var c_z = vertices[ indexC * 3 + 2 ]; 37109 var d_x = vertices[ indexD * 3 ]; 37110 var d_y = vertices[ indexD * 3 + 1 ]; 37111 var d_z = vertices[ indexD * 3 + 2 ]; 37112 37113 if ( Math.abs( a_y - b_y ) < 0.01 ) { 37114 37115 return [ 37116 new Vector2( a_x, 1 - a_z ), 37117 new Vector2( b_x, 1 - b_z ), 37118 new Vector2( c_x, 1 - c_z ), 37119 new Vector2( d_x, 1 - d_z ) 37120 ]; 37121 37122 } else { 37123 37124 return [ 37125 new Vector2( a_y, 1 - a_z ), 37126 new Vector2( b_y, 1 - b_z ), 37127 new Vector2( c_y, 1 - c_z ), 37128 new Vector2( d_y, 1 - d_z ) 37129 ]; 37130 37131 } 37132 37133 } 37134 }; 37135 37136 function toJSON( shapes, options, data ) { 37137 37138 // 37139 37140 data.shapes = []; 37141 37142 if ( Array.isArray( shapes ) ) { 37143 37144 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 37145 37146 var shape = shapes[ i ]; 37147 37148 data.shapes.push( shape.uuid ); 37149 37150 } 37151 37152 } else { 37153 37154 data.shapes.push( shapes.uuid ); 37155 37156 } 37157 37158 // 37159 37160 if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); 37161 37162 return data; 37163 37164 } 37165 37166 /** 37167 * @author zz85 / http://www.lab4games.net/zz85/blog 37168 * @author alteredq / http://alteredqualia.com/ 37169 * 37170 * Text = 3D Text 37171 * 37172 * parameters = { 37173 * font: <THREE.Font>, // font 37174 * 37175 * size: <float>, // size of the text 37176 * height: <float>, // thickness to extrude text 37177 * curveSegments: <int>, // number of points on the curves 37178 * 37179 * bevelEnabled: <bool>, // turn on bevel 37180 * bevelThickness: <float>, // how deep into text bevel goes 37181 * bevelSize: <float> // how far from text outline is bevel 37182 * } 37183 */ 37184 37185 // TextGeometry 37186 37187 function TextGeometry( text, parameters ) { 37188 37189 Geometry.call( this ); 37190 37191 this.type = 'TextGeometry'; 37192 37193 this.parameters = { 37194 text: text, 37195 parameters: parameters 37196 }; 37197 37198 this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) ); 37199 this.mergeVertices(); 37200 37201 } 37202 37203 TextGeometry.prototype = Object.create( Geometry.prototype ); 37204 TextGeometry.prototype.constructor = TextGeometry; 37205 37206 // TextBufferGeometry 37207 37208 function TextBufferGeometry( text, parameters ) { 37209 37210 parameters = parameters || {}; 37211 37212 var font = parameters.font; 37213 37214 if ( ! ( font && font.isFont ) ) { 37215 37216 console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' ); 37217 return new Geometry(); 37218 37219 } 37220 37221 var shapes = font.generateShapes( text, parameters.size, parameters.curveSegments ); 37222 37223 // translate parameters to ExtrudeGeometry API 37224 37225 parameters.depth = parameters.height !== undefined ? parameters.height : 50; 37226 37227 // defaults 37228 37229 if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; 37230 if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; 37231 if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; 37232 37233 ExtrudeBufferGeometry.call( this, shapes, parameters ); 37234 37235 this.type = 'TextBufferGeometry'; 37236 37237 } 37238 37239 TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype ); 37240 TextBufferGeometry.prototype.constructor = TextBufferGeometry; 37241 37242 /** 37243 * @author mrdoob / http://mrdoob.com/ 37244 * @author benaadams / https://twitter.com/ben_a_adams 37245 * @author Mugen87 / https://github.com/Mugen87 37246 */ 37247 37248 // SphereGeometry 37249 37250 function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { 37251 37252 Geometry.call( this ); 37253 37254 this.type = 'SphereGeometry'; 37255 37256 this.parameters = { 37257 radius: radius, 37258 widthSegments: widthSegments, 37259 heightSegments: heightSegments, 37260 phiStart: phiStart, 37261 phiLength: phiLength, 37262 thetaStart: thetaStart, 37263 thetaLength: thetaLength 37264 }; 37265 37266 this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) ); 37267 this.mergeVertices(); 37268 37269 } 37270 37271 SphereGeometry.prototype = Object.create( Geometry.prototype ); 37272 SphereGeometry.prototype.constructor = SphereGeometry; 37273 37274 // SphereBufferGeometry 37275 37276 function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { 37277 37278 BufferGeometry.call( this ); 37279 37280 this.type = 'SphereBufferGeometry'; 37281 37282 this.parameters = { 37283 radius: radius, 37284 widthSegments: widthSegments, 37285 heightSegments: heightSegments, 37286 phiStart: phiStart, 37287 phiLength: phiLength, 37288 thetaStart: thetaStart, 37289 thetaLength: thetaLength 37290 }; 37291 37292 radius = radius || 1; 37293 37294 widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 ); 37295 heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 ); 37296 37297 phiStart = phiStart !== undefined ? phiStart : 0; 37298 phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; 37299 37300 thetaStart = thetaStart !== undefined ? thetaStart : 0; 37301 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; 37302 37303 var thetaEnd = thetaStart + thetaLength; 37304 37305 var ix, iy; 37306 37307 var index = 0; 37308 var grid = []; 37309 37310 var vertex = new Vector3(); 37311 var normal = new Vector3(); 37312 37313 // buffers 37314 37315 var indices = []; 37316 var vertices = []; 37317 var normals = []; 37318 var uvs = []; 37319 37320 // generate vertices, normals and uvs 37321 37322 for ( iy = 0; iy <= heightSegments; iy ++ ) { 37323 37324 var verticesRow = []; 37325 37326 var v = iy / heightSegments; 37327 37328 for ( ix = 0; ix <= widthSegments; ix ++ ) { 37329 37330 var u = ix / widthSegments; 37331 37332 // vertex 37333 37334 vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); 37335 vertex.y = radius * Math.cos( thetaStart + v * thetaLength ); 37336 vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); 37337 37338 vertices.push( vertex.x, vertex.y, vertex.z ); 37339 37340 // normal 37341 37342 normal.set( vertex.x, vertex.y, vertex.z ).normalize(); 37343 normals.push( normal.x, normal.y, normal.z ); 37344 37345 // uv 37346 37347 uvs.push( u, 1 - v ); 37348 37349 verticesRow.push( index ++ ); 37350 37351 } 37352 37353 grid.push( verticesRow ); 37354 37355 } 37356 37357 // indices 37358 37359 for ( iy = 0; iy < heightSegments; iy ++ ) { 37360 37361 for ( ix = 0; ix < widthSegments; ix ++ ) { 37362 37363 var a = grid[ iy ][ ix + 1 ]; 37364 var b = grid[ iy ][ ix ]; 37365 var c = grid[ iy + 1 ][ ix ]; 37366 var d = grid[ iy + 1 ][ ix + 1 ]; 37367 37368 if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); 37369 if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); 37370 37371 } 37372 37373 } 37374 37375 // build geometry 37376 37377 this.setIndex( indices ); 37378 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 37379 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 37380 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 37381 37382 } 37383 37384 SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 37385 SphereBufferGeometry.prototype.constructor = SphereBufferGeometry; 37386 37387 /** 37388 * @author Kaleb Murphy 37389 * @author Mugen87 / https://github.com/Mugen87 37390 */ 37391 37392 // RingGeometry 37393 37394 function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { 37395 37396 Geometry.call( this ); 37397 37398 this.type = 'RingGeometry'; 37399 37400 this.parameters = { 37401 innerRadius: innerRadius, 37402 outerRadius: outerRadius, 37403 thetaSegments: thetaSegments, 37404 phiSegments: phiSegments, 37405 thetaStart: thetaStart, 37406 thetaLength: thetaLength 37407 }; 37408 37409 this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) ); 37410 this.mergeVertices(); 37411 37412 } 37413 37414 RingGeometry.prototype = Object.create( Geometry.prototype ); 37415 RingGeometry.prototype.constructor = RingGeometry; 37416 37417 // RingBufferGeometry 37418 37419 function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { 37420 37421 BufferGeometry.call( this ); 37422 37423 this.type = 'RingBufferGeometry'; 37424 37425 this.parameters = { 37426 innerRadius: innerRadius, 37427 outerRadius: outerRadius, 37428 thetaSegments: thetaSegments, 37429 phiSegments: phiSegments, 37430 thetaStart: thetaStart, 37431 thetaLength: thetaLength 37432 }; 37433 37434 innerRadius = innerRadius || 0.5; 37435 outerRadius = outerRadius || 1; 37436 37437 thetaStart = thetaStart !== undefined ? thetaStart : 0; 37438 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 37439 37440 thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; 37441 phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1; 37442 37443 // buffers 37444 37445 var indices = []; 37446 var vertices = []; 37447 var normals = []; 37448 var uvs = []; 37449 37450 // some helper variables 37451 37452 var segment; 37453 var radius = innerRadius; 37454 var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); 37455 var vertex = new Vector3(); 37456 var uv = new Vector2(); 37457 var j, i; 37458 37459 // generate vertices, normals and uvs 37460 37461 for ( j = 0; j <= phiSegments; j ++ ) { 37462 37463 for ( i = 0; i <= thetaSegments; i ++ ) { 37464 37465 // values are generate from the inside of the ring to the outside 37466 37467 segment = thetaStart + i / thetaSegments * thetaLength; 37468 37469 // vertex 37470 37471 vertex.x = radius * Math.cos( segment ); 37472 vertex.y = radius * Math.sin( segment ); 37473 37474 vertices.push( vertex.x, vertex.y, vertex.z ); 37475 37476 // normal 37477 37478 normals.push( 0, 0, 1 ); 37479 37480 // uv 37481 37482 uv.x = ( vertex.x / outerRadius + 1 ) / 2; 37483 uv.y = ( vertex.y / outerRadius + 1 ) / 2; 37484 37485 uvs.push( uv.x, uv.y ); 37486 37487 } 37488 37489 // increase the radius for next row of vertices 37490 37491 radius += radiusStep; 37492 37493 } 37494 37495 // indices 37496 37497 for ( j = 0; j < phiSegments; j ++ ) { 37498 37499 var thetaSegmentLevel = j * ( thetaSegments + 1 ); 37500 37501 for ( i = 0; i < thetaSegments; i ++ ) { 37502 37503 segment = i + thetaSegmentLevel; 37504 37505 var a = segment; 37506 var b = segment + thetaSegments + 1; 37507 var c = segment + thetaSegments + 2; 37508 var d = segment + 1; 37509 37510 // faces 37511 37512 indices.push( a, b, d ); 37513 indices.push( b, c, d ); 37514 37515 } 37516 37517 } 37518 37519 // build geometry 37520 37521 this.setIndex( indices ); 37522 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 37523 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 37524 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 37525 37526 } 37527 37528 RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 37529 RingBufferGeometry.prototype.constructor = RingBufferGeometry; 37530 37531 /** 37532 * @author astrodud / http://astrodud.isgreat.org/ 37533 * @author zz85 / https://github.com/zz85 37534 * @author bhouston / http://clara.io 37535 * @author Mugen87 / https://github.com/Mugen87 37536 */ 37537 37538 // LatheGeometry 37539 37540 function LatheGeometry( points, segments, phiStart, phiLength ) { 37541 37542 Geometry.call( this ); 37543 37544 this.type = 'LatheGeometry'; 37545 37546 this.parameters = { 37547 points: points, 37548 segments: segments, 37549 phiStart: phiStart, 37550 phiLength: phiLength 37551 }; 37552 37553 this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) ); 37554 this.mergeVertices(); 37555 37556 } 37557 37558 LatheGeometry.prototype = Object.create( Geometry.prototype ); 37559 LatheGeometry.prototype.constructor = LatheGeometry; 37560 37561 // LatheBufferGeometry 37562 37563 function LatheBufferGeometry( points, segments, phiStart, phiLength ) { 37564 37565 BufferGeometry.call( this ); 37566 37567 this.type = 'LatheBufferGeometry'; 37568 37569 this.parameters = { 37570 points: points, 37571 segments: segments, 37572 phiStart: phiStart, 37573 phiLength: phiLength 37574 }; 37575 37576 segments = Math.floor( segments ) || 12; 37577 phiStart = phiStart || 0; 37578 phiLength = phiLength || Math.PI * 2; 37579 37580 // clamp phiLength so it's in range of [ 0, 2PI ] 37581 37582 phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); 37583 37584 37585 // buffers 37586 37587 var indices = []; 37588 var vertices = []; 37589 var uvs = []; 37590 37591 // helper variables 37592 37593 var base; 37594 var inverseSegments = 1.0 / segments; 37595 var vertex = new Vector3(); 37596 var uv = new Vector2(); 37597 var i, j; 37598 37599 // generate vertices and uvs 37600 37601 for ( i = 0; i <= segments; i ++ ) { 37602 37603 var phi = phiStart + i * inverseSegments * phiLength; 37604 37605 var sin = Math.sin( phi ); 37606 var cos = Math.cos( phi ); 37607 37608 for ( j = 0; j <= ( points.length - 1 ); j ++ ) { 37609 37610 // vertex 37611 37612 vertex.x = points[ j ].x * sin; 37613 vertex.y = points[ j ].y; 37614 vertex.z = points[ j ].x * cos; 37615 37616 vertices.push( vertex.x, vertex.y, vertex.z ); 37617 37618 // uv 37619 37620 uv.x = i / segments; 37621 uv.y = j / ( points.length - 1 ); 37622 37623 uvs.push( uv.x, uv.y ); 37624 37625 37626 } 37627 37628 } 37629 37630 // indices 37631 37632 for ( i = 0; i < segments; i ++ ) { 37633 37634 for ( j = 0; j < ( points.length - 1 ); j ++ ) { 37635 37636 base = j + i * points.length; 37637 37638 var a = base; 37639 var b = base + points.length; 37640 var c = base + points.length + 1; 37641 var d = base + 1; 37642 37643 // faces 37644 37645 indices.push( a, b, d ); 37646 indices.push( b, c, d ); 37647 37648 } 37649 37650 } 37651 37652 // build geometry 37653 37654 this.setIndex( indices ); 37655 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 37656 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 37657 37658 // generate normals 37659 37660 this.computeVertexNormals(); 37661 37662 // if the geometry is closed, we need to average the normals along the seam. 37663 // because the corresponding vertices are identical (but still have different UVs). 37664 37665 if ( phiLength === Math.PI * 2 ) { 37666 37667 var normals = this.attributes.normal.array; 37668 var n1 = new Vector3(); 37669 var n2 = new Vector3(); 37670 var n = new Vector3(); 37671 37672 // this is the buffer offset for the last line of vertices 37673 37674 base = segments * points.length * 3; 37675 37676 for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) { 37677 37678 // select the normal of the vertex in the first line 37679 37680 n1.x = normals[ j + 0 ]; 37681 n1.y = normals[ j + 1 ]; 37682 n1.z = normals[ j + 2 ]; 37683 37684 // select the normal of the vertex in the last line 37685 37686 n2.x = normals[ base + j + 0 ]; 37687 n2.y = normals[ base + j + 1 ]; 37688 n2.z = normals[ base + j + 2 ]; 37689 37690 // average normals 37691 37692 n.addVectors( n1, n2 ).normalize(); 37693 37694 // assign the new values to both normals 37695 37696 normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; 37697 normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; 37698 normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; 37699 37700 } 37701 37702 } 37703 37704 } 37705 37706 LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 37707 LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; 37708 37709 /** 37710 * @author jonobr1 / http://jonobr1.com 37711 * @author Mugen87 / https://github.com/Mugen87 37712 */ 37713 37714 // ShapeGeometry 37715 37716 function ShapeGeometry( shapes, curveSegments ) { 37717 37718 Geometry.call( this ); 37719 37720 this.type = 'ShapeGeometry'; 37721 37722 if ( typeof curveSegments === 'object' ) { 37723 37724 console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' ); 37725 37726 curveSegments = curveSegments.curveSegments; 37727 37728 } 37729 37730 this.parameters = { 37731 shapes: shapes, 37732 curveSegments: curveSegments 37733 }; 37734 37735 this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) ); 37736 this.mergeVertices(); 37737 37738 } 37739 37740 ShapeGeometry.prototype = Object.create( Geometry.prototype ); 37741 ShapeGeometry.prototype.constructor = ShapeGeometry; 37742 37743 ShapeGeometry.prototype.toJSON = function () { 37744 37745 var data = Geometry.prototype.toJSON.call( this ); 37746 37747 var shapes = this.parameters.shapes; 37748 37749 return toJSON$1( shapes, data ); 37750 37751 }; 37752 37753 // ShapeBufferGeometry 37754 37755 function ShapeBufferGeometry( shapes, curveSegments ) { 37756 37757 BufferGeometry.call( this ); 37758 37759 this.type = 'ShapeBufferGeometry'; 37760 37761 this.parameters = { 37762 shapes: shapes, 37763 curveSegments: curveSegments 37764 }; 37765 37766 curveSegments = curveSegments || 12; 37767 37768 // buffers 37769 37770 var indices = []; 37771 var vertices = []; 37772 var normals = []; 37773 var uvs = []; 37774 37775 // helper variables 37776 37777 var groupStart = 0; 37778 var groupCount = 0; 37779 37780 // allow single and array values for "shapes" parameter 37781 37782 if ( Array.isArray( shapes ) === false ) { 37783 37784 addShape( shapes ); 37785 37786 } else { 37787 37788 for ( var i = 0; i < shapes.length; i ++ ) { 37789 37790 addShape( shapes[ i ] ); 37791 37792 this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support 37793 37794 groupStart += groupCount; 37795 groupCount = 0; 37796 37797 } 37798 37799 } 37800 37801 // build geometry 37802 37803 this.setIndex( indices ); 37804 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 37805 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 37806 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 37807 37808 37809 // helper functions 37810 37811 function addShape( shape ) { 37812 37813 var i, l, shapeHole; 37814 37815 var indexOffset = vertices.length / 3; 37816 var points = shape.extractPoints( curveSegments ); 37817 37818 var shapeVertices = points.shape; 37819 var shapeHoles = points.holes; 37820 37821 // check direction of vertices 37822 37823 if ( ShapeUtils.isClockWise( shapeVertices ) === false ) { 37824 37825 shapeVertices = shapeVertices.reverse(); 37826 37827 // also check if holes are in the opposite direction 37828 37829 for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { 37830 37831 shapeHole = shapeHoles[ i ]; 37832 37833 if ( ShapeUtils.isClockWise( shapeHole ) === true ) { 37834 37835 shapeHoles[ i ] = shapeHole.reverse(); 37836 37837 } 37838 37839 } 37840 37841 } 37842 37843 var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles ); 37844 37845 // join vertices of inner and outer paths to a single array 37846 37847 for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { 37848 37849 shapeHole = shapeHoles[ i ]; 37850 shapeVertices = shapeVertices.concat( shapeHole ); 37851 37852 } 37853 37854 // vertices, normals, uvs 37855 37856 for ( i = 0, l = shapeVertices.length; i < l; i ++ ) { 37857 37858 var vertex = shapeVertices[ i ]; 37859 37860 vertices.push( vertex.x, vertex.y, 0 ); 37861 normals.push( 0, 0, 1 ); 37862 uvs.push( vertex.x, vertex.y ); // world uvs 37863 37864 } 37865 37866 // incides 37867 37868 for ( i = 0, l = faces.length; i < l; i ++ ) { 37869 37870 var face = faces[ i ]; 37871 37872 var a = face[ 0 ] + indexOffset; 37873 var b = face[ 1 ] + indexOffset; 37874 var c = face[ 2 ] + indexOffset; 37875 37876 indices.push( a, b, c ); 37877 groupCount += 3; 37878 37879 } 37880 37881 } 37882 37883 } 37884 37885 ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 37886 ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry; 37887 37888 ShapeBufferGeometry.prototype.toJSON = function () { 37889 37890 var data = BufferGeometry.prototype.toJSON.call( this ); 37891 37892 var shapes = this.parameters.shapes; 37893 37894 return toJSON$1( shapes, data ); 37895 37896 }; 37897 37898 // 37899 37900 function toJSON$1( shapes, data ) { 37901 37902 data.shapes = []; 37903 37904 if ( Array.isArray( shapes ) ) { 37905 37906 for ( var i = 0, l = shapes.length; i < l; i ++ ) { 37907 37908 var shape = shapes[ i ]; 37909 37910 data.shapes.push( shape.uuid ); 37911 37912 } 37913 37914 } else { 37915 37916 data.shapes.push( shapes.uuid ); 37917 37918 } 37919 37920 return data; 37921 37922 } 37923 37924 /** 37925 * @author WestLangley / http://github.com/WestLangley 37926 * @author Mugen87 / https://github.com/Mugen87 37927 */ 37928 37929 function EdgesGeometry( geometry, thresholdAngle ) { 37930 37931 BufferGeometry.call( this ); 37932 37933 this.type = 'EdgesGeometry'; 37934 37935 this.parameters = { 37936 thresholdAngle: thresholdAngle 37937 }; 37938 37939 thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; 37940 37941 // buffer 37942 37943 var vertices = []; 37944 37945 // helper variables 37946 37947 var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); 37948 var edge = [ 0, 0 ], edges = {}, edge1, edge2; 37949 var key, keys = [ 'a', 'b', 'c' ]; 37950 37951 // prepare source geometry 37952 37953 var geometry2; 37954 37955 if ( geometry.isBufferGeometry ) { 37956 37957 geometry2 = new Geometry(); 37958 geometry2.fromBufferGeometry( geometry ); 37959 37960 } else { 37961 37962 geometry2 = geometry.clone(); 37963 37964 } 37965 37966 geometry2.mergeVertices(); 37967 geometry2.computeFaceNormals(); 37968 37969 var sourceVertices = geometry2.vertices; 37970 var faces = geometry2.faces; 37971 37972 // now create a data structure where each entry represents an edge with its adjoining faces 37973 37974 for ( var i = 0, l = faces.length; i < l; i ++ ) { 37975 37976 var face = faces[ i ]; 37977 37978 for ( var j = 0; j < 3; j ++ ) { 37979 37980 edge1 = face[ keys[ j ] ]; 37981 edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; 37982 edge[ 0 ] = Math.min( edge1, edge2 ); 37983 edge[ 1 ] = Math.max( edge1, edge2 ); 37984 37985 key = edge[ 0 ] + ',' + edge[ 1 ]; 37986 37987 if ( edges[ key ] === undefined ) { 37988 37989 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined }; 37990 37991 } else { 37992 37993 edges[ key ].face2 = i; 37994 37995 } 37996 37997 } 37998 37999 } 38000 38001 // generate vertices 38002 38003 for ( key in edges ) { 38004 38005 var e = edges[ key ]; 38006 38007 // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree. 38008 38009 if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) { 38010 38011 var vertex = sourceVertices[ e.index1 ]; 38012 vertices.push( vertex.x, vertex.y, vertex.z ); 38013 38014 vertex = sourceVertices[ e.index2 ]; 38015 vertices.push( vertex.x, vertex.y, vertex.z ); 38016 38017 } 38018 38019 } 38020 38021 // build geometry 38022 38023 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 38024 38025 } 38026 38027 EdgesGeometry.prototype = Object.create( BufferGeometry.prototype ); 38028 EdgesGeometry.prototype.constructor = EdgesGeometry; 38029 38030 /** 38031 * @author mrdoob / http://mrdoob.com/ 38032 * @author Mugen87 / https://github.com/Mugen87 38033 */ 38034 38035 // CylinderGeometry 38036 38037 function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 38038 38039 Geometry.call( this ); 38040 38041 this.type = 'CylinderGeometry'; 38042 38043 this.parameters = { 38044 radiusTop: radiusTop, 38045 radiusBottom: radiusBottom, 38046 height: height, 38047 radialSegments: radialSegments, 38048 heightSegments: heightSegments, 38049 openEnded: openEnded, 38050 thetaStart: thetaStart, 38051 thetaLength: thetaLength 38052 }; 38053 38054 this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); 38055 this.mergeVertices(); 38056 38057 } 38058 38059 CylinderGeometry.prototype = Object.create( Geometry.prototype ); 38060 CylinderGeometry.prototype.constructor = CylinderGeometry; 38061 38062 // CylinderBufferGeometry 38063 38064 function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 38065 38066 BufferGeometry.call( this ); 38067 38068 this.type = 'CylinderBufferGeometry'; 38069 38070 this.parameters = { 38071 radiusTop: radiusTop, 38072 radiusBottom: radiusBottom, 38073 height: height, 38074 radialSegments: radialSegments, 38075 heightSegments: heightSegments, 38076 openEnded: openEnded, 38077 thetaStart: thetaStart, 38078 thetaLength: thetaLength 38079 }; 38080 38081 var scope = this; 38082 38083 radiusTop = radiusTop !== undefined ? radiusTop : 1; 38084 radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; 38085 height = height || 1; 38086 38087 radialSegments = Math.floor( radialSegments ) || 8; 38088 heightSegments = Math.floor( heightSegments ) || 1; 38089 38090 openEnded = openEnded !== undefined ? openEnded : false; 38091 thetaStart = thetaStart !== undefined ? thetaStart : 0.0; 38092 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 38093 38094 // buffers 38095 38096 var indices = []; 38097 var vertices = []; 38098 var normals = []; 38099 var uvs = []; 38100 38101 // helper variables 38102 38103 var index = 0; 38104 var indexArray = []; 38105 var halfHeight = height / 2; 38106 var groupStart = 0; 38107 38108 // generate geometry 38109 38110 generateTorso(); 38111 38112 if ( openEnded === false ) { 38113 38114 if ( radiusTop > 0 ) generateCap( true ); 38115 if ( radiusBottom > 0 ) generateCap( false ); 38116 38117 } 38118 38119 // build geometry 38120 38121 this.setIndex( indices ); 38122 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 38123 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 38124 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 38125 38126 function generateTorso() { 38127 38128 var x, y; 38129 var normal = new Vector3(); 38130 var vertex = new Vector3(); 38131 38132 var groupCount = 0; 38133 38134 // this will be used to calculate the normal 38135 var slope = ( radiusBottom - radiusTop ) / height; 38136 38137 // generate vertices, normals and uvs 38138 38139 for ( y = 0; y <= heightSegments; y ++ ) { 38140 38141 var indexRow = []; 38142 38143 var v = y / heightSegments; 38144 38145 // calculate the radius of the current row 38146 38147 var radius = v * ( radiusBottom - radiusTop ) + radiusTop; 38148 38149 for ( x = 0; x <= radialSegments; x ++ ) { 38150 38151 var u = x / radialSegments; 38152 38153 var theta = u * thetaLength + thetaStart; 38154 38155 var sinTheta = Math.sin( theta ); 38156 var cosTheta = Math.cos( theta ); 38157 38158 // vertex 38159 38160 vertex.x = radius * sinTheta; 38161 vertex.y = - v * height + halfHeight; 38162 vertex.z = radius * cosTheta; 38163 vertices.push( vertex.x, vertex.y, vertex.z ); 38164 38165 // normal 38166 38167 normal.set( sinTheta, slope, cosTheta ).normalize(); 38168 normals.push( normal.x, normal.y, normal.z ); 38169 38170 // uv 38171 38172 uvs.push( u, 1 - v ); 38173 38174 // save index of vertex in respective row 38175 38176 indexRow.push( index ++ ); 38177 38178 } 38179 38180 // now save vertices of the row in our index array 38181 38182 indexArray.push( indexRow ); 38183 38184 } 38185 38186 // generate indices 38187 38188 for ( x = 0; x < radialSegments; x ++ ) { 38189 38190 for ( y = 0; y < heightSegments; y ++ ) { 38191 38192 // we use the index array to access the correct indices 38193 38194 var a = indexArray[ y ][ x ]; 38195 var b = indexArray[ y + 1 ][ x ]; 38196 var c = indexArray[ y + 1 ][ x + 1 ]; 38197 var d = indexArray[ y ][ x + 1 ]; 38198 38199 // faces 38200 38201 indices.push( a, b, d ); 38202 indices.push( b, c, d ); 38203 38204 // update group counter 38205 38206 groupCount += 6; 38207 38208 } 38209 38210 } 38211 38212 // add a group to the geometry. this will ensure multi material support 38213 38214 scope.addGroup( groupStart, groupCount, 0 ); 38215 38216 // calculate new start value for groups 38217 38218 groupStart += groupCount; 38219 38220 } 38221 38222 function generateCap( top ) { 38223 38224 var x, centerIndexStart, centerIndexEnd; 38225 38226 var uv = new Vector2(); 38227 var vertex = new Vector3(); 38228 38229 var groupCount = 0; 38230 38231 var radius = ( top === true ) ? radiusTop : radiusBottom; 38232 var sign = ( top === true ) ? 1 : - 1; 38233 38234 // save the index of the first center vertex 38235 centerIndexStart = index; 38236 38237 // first we generate the center vertex data of the cap. 38238 // because the geometry needs one set of uvs per face, 38239 // we must generate a center vertex per face/segment 38240 38241 for ( x = 1; x <= radialSegments; x ++ ) { 38242 38243 // vertex 38244 38245 vertices.push( 0, halfHeight * sign, 0 ); 38246 38247 // normal 38248 38249 normals.push( 0, sign, 0 ); 38250 38251 // uv 38252 38253 uvs.push( 0.5, 0.5 ); 38254 38255 // increase index 38256 38257 index ++; 38258 38259 } 38260 38261 // save the index of the last center vertex 38262 38263 centerIndexEnd = index; 38264 38265 // now we generate the surrounding vertices, normals and uvs 38266 38267 for ( x = 0; x <= radialSegments; x ++ ) { 38268 38269 var u = x / radialSegments; 38270 var theta = u * thetaLength + thetaStart; 38271 38272 var cosTheta = Math.cos( theta ); 38273 var sinTheta = Math.sin( theta ); 38274 38275 // vertex 38276 38277 vertex.x = radius * sinTheta; 38278 vertex.y = halfHeight * sign; 38279 vertex.z = radius * cosTheta; 38280 vertices.push( vertex.x, vertex.y, vertex.z ); 38281 38282 // normal 38283 38284 normals.push( 0, sign, 0 ); 38285 38286 // uv 38287 38288 uv.x = ( cosTheta * 0.5 ) + 0.5; 38289 uv.y = ( sinTheta * 0.5 * sign ) + 0.5; 38290 uvs.push( uv.x, uv.y ); 38291 38292 // increase index 38293 38294 index ++; 38295 38296 } 38297 38298 // generate indices 38299 38300 for ( x = 0; x < radialSegments; x ++ ) { 38301 38302 var c = centerIndexStart + x; 38303 var i = centerIndexEnd + x; 38304 38305 if ( top === true ) { 38306 38307 // face top 38308 38309 indices.push( i, i + 1, c ); 38310 38311 } else { 38312 38313 // face bottom 38314 38315 indices.push( i + 1, i, c ); 38316 38317 } 38318 38319 groupCount += 3; 38320 38321 } 38322 38323 // add a group to the geometry. this will ensure multi material support 38324 38325 scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); 38326 38327 // calculate new start value for groups 38328 38329 groupStart += groupCount; 38330 38331 } 38332 38333 } 38334 38335 CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 38336 CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry; 38337 38338 /** 38339 * @author abelnation / http://github.com/abelnation 38340 */ 38341 38342 // ConeGeometry 38343 38344 function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 38345 38346 CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); 38347 38348 this.type = 'ConeGeometry'; 38349 38350 this.parameters = { 38351 radius: radius, 38352 height: height, 38353 radialSegments: radialSegments, 38354 heightSegments: heightSegments, 38355 openEnded: openEnded, 38356 thetaStart: thetaStart, 38357 thetaLength: thetaLength 38358 }; 38359 38360 } 38361 38362 ConeGeometry.prototype = Object.create( CylinderGeometry.prototype ); 38363 ConeGeometry.prototype.constructor = ConeGeometry; 38364 38365 // ConeBufferGeometry 38366 38367 function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { 38368 38369 CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); 38370 38371 this.type = 'ConeBufferGeometry'; 38372 38373 this.parameters = { 38374 radius: radius, 38375 height: height, 38376 radialSegments: radialSegments, 38377 heightSegments: heightSegments, 38378 openEnded: openEnded, 38379 thetaStart: thetaStart, 38380 thetaLength: thetaLength 38381 }; 38382 38383 } 38384 38385 ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype ); 38386 ConeBufferGeometry.prototype.constructor = ConeBufferGeometry; 38387 38388 /** 38389 * @author benaadams / https://twitter.com/ben_a_adams 38390 * @author Mugen87 / https://github.com/Mugen87 38391 * @author hughes 38392 */ 38393 38394 // CircleGeometry 38395 38396 function CircleGeometry( radius, segments, thetaStart, thetaLength ) { 38397 38398 Geometry.call( this ); 38399 38400 this.type = 'CircleGeometry'; 38401 38402 this.parameters = { 38403 radius: radius, 38404 segments: segments, 38405 thetaStart: thetaStart, 38406 thetaLength: thetaLength 38407 }; 38408 38409 this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) ); 38410 this.mergeVertices(); 38411 38412 } 38413 38414 CircleGeometry.prototype = Object.create( Geometry.prototype ); 38415 CircleGeometry.prototype.constructor = CircleGeometry; 38416 38417 // CircleBufferGeometry 38418 38419 function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) { 38420 38421 BufferGeometry.call( this ); 38422 38423 this.type = 'CircleBufferGeometry'; 38424 38425 this.parameters = { 38426 radius: radius, 38427 segments: segments, 38428 thetaStart: thetaStart, 38429 thetaLength: thetaLength 38430 }; 38431 38432 radius = radius || 1; 38433 segments = segments !== undefined ? Math.max( 3, segments ) : 8; 38434 38435 thetaStart = thetaStart !== undefined ? thetaStart : 0; 38436 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; 38437 38438 // buffers 38439 38440 var indices = []; 38441 var vertices = []; 38442 var normals = []; 38443 var uvs = []; 38444 38445 // helper variables 38446 38447 var i, s; 38448 var vertex = new Vector3(); 38449 var uv = new Vector2(); 38450 38451 // center point 38452 38453 vertices.push( 0, 0, 0 ); 38454 normals.push( 0, 0, 1 ); 38455 uvs.push( 0.5, 0.5 ); 38456 38457 for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) { 38458 38459 var segment = thetaStart + s / segments * thetaLength; 38460 38461 // vertex 38462 38463 vertex.x = radius * Math.cos( segment ); 38464 vertex.y = radius * Math.sin( segment ); 38465 38466 vertices.push( vertex.x, vertex.y, vertex.z ); 38467 38468 // normal 38469 38470 normals.push( 0, 0, 1 ); 38471 38472 // uvs 38473 38474 uv.x = ( vertices[ i ] / radius + 1 ) / 2; 38475 uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; 38476 38477 uvs.push( uv.x, uv.y ); 38478 38479 } 38480 38481 // indices 38482 38483 for ( i = 1; i <= segments; i ++ ) { 38484 38485 indices.push( i, i + 1, 0 ); 38486 38487 } 38488 38489 // build geometry 38490 38491 this.setIndex( indices ); 38492 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 38493 this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); 38494 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); 38495 38496 } 38497 38498 CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); 38499 CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; 38500 38501 38502 38503 var Geometries = /*#__PURE__*/Object.freeze({ 38504 WireframeGeometry: WireframeGeometry, 38505 ParametricGeometry: ParametricGeometry, 38506 ParametricBufferGeometry: ParametricBufferGeometry, 38507 TetrahedronGeometry: TetrahedronGeometry, 38508 TetrahedronBufferGeometry: TetrahedronBufferGeometry, 38509 OctahedronGeometry: OctahedronGeometry, 38510 OctahedronBufferGeometry: OctahedronBufferGeometry, 38511 IcosahedronGeometry: IcosahedronGeometry, 38512 IcosahedronBufferGeometry: IcosahedronBufferGeometry, 38513 DodecahedronGeometry: DodecahedronGeometry, 38514 DodecahedronBufferGeometry: DodecahedronBufferGeometry, 38515 PolyhedronGeometry: PolyhedronGeometry, 38516 PolyhedronBufferGeometry: PolyhedronBufferGeometry, 38517 TubeGeometry: TubeGeometry, 38518 TubeBufferGeometry: TubeBufferGeometry, 38519 TorusKnotGeometry: TorusKnotGeometry, 38520 TorusKnotBufferGeometry: TorusKnotBufferGeometry, 38521 TorusGeometry: TorusGeometry, 38522 TorusBufferGeometry: TorusBufferGeometry, 38523 TextGeometry: TextGeometry, 38524 TextBufferGeometry: TextBufferGeometry, 38525 SphereGeometry: SphereGeometry, 38526 SphereBufferGeometry: SphereBufferGeometry, 38527 RingGeometry: RingGeometry, 38528 RingBufferGeometry: RingBufferGeometry, 38529 PlaneGeometry: PlaneGeometry, 38530 PlaneBufferGeometry: PlaneBufferGeometry, 38531 LatheGeometry: LatheGeometry, 38532 LatheBufferGeometry: LatheBufferGeometry, 38533 ShapeGeometry: ShapeGeometry, 38534 ShapeBufferGeometry: ShapeBufferGeometry, 38535 ExtrudeGeometry: ExtrudeGeometry, 38536 ExtrudeBufferGeometry: ExtrudeBufferGeometry, 38537 EdgesGeometry: EdgesGeometry, 38538 ConeGeometry: ConeGeometry, 38539 ConeBufferGeometry: ConeBufferGeometry, 38540 CylinderGeometry: CylinderGeometry, 38541 CylinderBufferGeometry: CylinderBufferGeometry, 38542 CircleGeometry: CircleGeometry, 38543 CircleBufferGeometry: CircleBufferGeometry, 38544 BoxGeometry: BoxGeometry, 38545 BoxBufferGeometry: BoxBufferGeometry 38546 }); 38547 38548 /** 38549 * @author mrdoob / http://mrdoob.com/ 38550 * 38551 * parameters = { 38552 * color: <THREE.Color> 38553 * } 38554 */ 38555 38556 function ShadowMaterial( parameters ) { 38557 38558 Material.call( this ); 38559 38560 this.type = 'ShadowMaterial'; 38561 38562 this.color = new Color( 0x000000 ); 38563 this.transparent = true; 38564 38565 this.setValues( parameters ); 38566 38567 } 38568 38569 ShadowMaterial.prototype = Object.create( Material.prototype ); 38570 ShadowMaterial.prototype.constructor = ShadowMaterial; 38571 38572 ShadowMaterial.prototype.isShadowMaterial = true; 38573 38574 ShadowMaterial.prototype.copy = function ( source ) { 38575 38576 Material.prototype.copy.call( this, source ); 38577 38578 this.color.copy( source.color ); 38579 38580 return this; 38581 38582 }; 38583 38584 /** 38585 * @author mrdoob / http://mrdoob.com/ 38586 */ 38587 38588 function RawShaderMaterial( parameters ) { 38589 38590 ShaderMaterial.call( this, parameters ); 38591 38592 this.type = 'RawShaderMaterial'; 38593 38594 } 38595 38596 RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype ); 38597 RawShaderMaterial.prototype.constructor = RawShaderMaterial; 38598 38599 RawShaderMaterial.prototype.isRawShaderMaterial = true; 38600 38601 /** 38602 * @author WestLangley / http://github.com/WestLangley 38603 * 38604 * parameters = { 38605 * color: <hex>, 38606 * roughness: <float>, 38607 * metalness: <float>, 38608 * opacity: <float>, 38609 * 38610 * map: new THREE.Texture( <Image> ), 38611 * 38612 * lightMap: new THREE.Texture( <Image> ), 38613 * lightMapIntensity: <float> 38614 * 38615 * aoMap: new THREE.Texture( <Image> ), 38616 * aoMapIntensity: <float> 38617 * 38618 * emissive: <hex>, 38619 * emissiveIntensity: <float> 38620 * emissiveMap: new THREE.Texture( <Image> ), 38621 * 38622 * bumpMap: new THREE.Texture( <Image> ), 38623 * bumpScale: <float>, 38624 * 38625 * normalMap: new THREE.Texture( <Image> ), 38626 * normalScale: <Vector2>,
38627 * 38628 * displacementMap: new THREE.Texture( <Image> ), 38629 * displacementScale: <float>, 38630 * displacementBias: <float>, 38631 * 38632 * roughnessMap: new THREE.Texture( <Image> ), 38633 * 38634 * metalnessMap: new THREE.Texture( <Image> ), 38635 * 38636 * alphaMap: new THREE.Texture( <Image> ), 38637 * 38638 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 38639 * envMapIntensity: <float> 38640 * 38641 * refractionRatio: <float>, 38642 * 38643 * wireframe: <boolean>, 38644 * wireframeLinewidth: <float>, 38645 * 38646 * skinning: <bool>, 38647 * morphTargets: <bool>, 38648 * morphNormals: <bool> 38649 * } 38650 */ 38651 38652 function MeshStandardMaterial( parameters ) { 38653 38654 Material.call( this ); 38655 38656 this.defines = { 'STANDARD': '' }; 38657 38658 this.type = 'MeshStandardMaterial'; 38659 38660 this.color = new Color( 0xffffff ); // diffuse 38661 this.roughness = 0.5; 38662 this.metalness = 0.5; 38663 38664 this.map = null; 38665 38666 this.lightMap = null; 38667 this.lightMapIntensity = 1.0; 38668 38669 this.aoMap = null; 38670 this.aoMapIntensity = 1.0; 38671 38672 this.emissive = new Color( 0x000000 ); 38673 this.emissiveIntensity = 1.0; 38674 this.emissiveMap = null; 38675 38676 this.bumpMap = null; 38677 this.bumpScale = 1; 38678 38679 this.normalMap = null; 38680 this.normalScale = new Vector2( 1, 1 ); 38681 38682 this.displacementMap = null; 38683 this.displacementScale = 1; 38684 this.displacementBias = 0; 38685 38686 this.roughnessMap = null; 38687 38688 this.metalnessMap = null; 38689 38690 this.alphaMap = null; 38691 38692 this.envMap = null; 38693 this.envMapIntensity = 1.0; 38694 38695 this.refractionRatio = 0.98; 38696 38697 this.wireframe = false; 38698 this.wireframeLinewidth = 1; 38699 this.wireframeLinecap = 'round'; 38700 this.wireframeLinejoin = 'round'; 38701 38702 this.skinning = false; 38703 this.morphTargets = false; 38704 this.morphNormals = false; 38705 38706 this.setValues( parameters ); 38707 38708 } 38709 38710 MeshStandardMaterial.prototype = Object.create( Material.prototype ); 38711 MeshStandardMaterial.prototype.constructor = MeshStandardMaterial; 38712 38713 MeshStandardMaterial.prototype.isMeshStandardMaterial = true; 38714 38715 MeshStandardMaterial.prototype.copy = function ( source ) { 38716 38717 Material.prototype.copy.call( this, source ); 38718 38719 this.defines = { 'STANDARD': '' }; 38720 38721 this.color.copy( source.color ); 38722 this.roughness = source.roughness; 38723 this.metalness = source.metalness; 38724 38725 this.map = source.map; 38726 38727 this.lightMap = source.lightMap; 38728 this.lightMapIntensity = source.lightMapIntensity; 38729 38730 this.aoMap = source.aoMap; 38731 this.aoMapIntensity = source.aoMapIntensity; 38732 38733 this.emissive.copy( source.emissive ); 38734 this.emissiveMap = source.emissiveMap; 38735 this.emissiveIntensity = source.emissiveIntensity; 38736 38737 this.bumpMap = source.bumpMap; 38738 this.bumpScale = source.bumpScale; 38739 38740 this.normalMap = source.normalMap; 38741 this.normalScale.copy( source.normalScale ); 38742 38743 this.displacementMap = source.displacementMap; 38744 this.displacementScale = source.displacementScale; 38745 this.displacementBias = source.displacementBias; 38746 38747 this.roughnessMap = source.roughnessMap; 38748 38749 this.metalnessMap = source.metalnessMap; 38750 38751 this.alphaMap = source.alphaMap; 38752 38753 this.envMap = source.envMap; 38754 this.envMapIntensity = source.envMapIntensity; 38755 38756 this.refractionRatio = source.refractionRatio; 38757 38758 this.wireframe = source.wireframe; 38759 this.wireframeLinewidth = source.wireframeLinewidth; 38760 this.wireframeLinecap = source.wireframeLinecap; 38761 this.wireframeLinejoin = source.wireframeLinejoin; 38762 38763 this.skinning = source.skinning; 38764 this.morphTargets = source.morphTargets; 38765 this.morphNormals = source.morphNormals; 38766 38767 return this; 38768 38769 }; 38770 38771 /** 38772 * @author WestLangley / http://github.com/WestLangley 38773 * 38774 * parameters = { 38775 * reflectivity: <float> 38776 * } 38777 */ 38778 38779 function MeshPhysicalMaterial( parameters ) { 38780 38781 MeshStandardMaterial.call( this ); 38782 38783 this.defines = { 'PHYSICAL': '' }; 38784 38785 this.type = 'MeshPhysicalMaterial'; 38786 38787 this.reflectivity = 0.5; // maps to F0 = 0.04 38788 38789 this.clearCoat = 0.0; 38790 this.clearCoatRoughness = 0.0; 38791 38792 this.setValues( parameters ); 38793 38794 } 38795 38796 MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype ); 38797 MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial; 38798 38799 MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; 38800 38801 MeshPhysicalMaterial.prototype.copy = function ( source ) { 38802 38803 MeshStandardMaterial.prototype.copy.call( this, source ); 38804 38805 this.defines = { 'PHYSICAL': '' }; 38806 38807 this.reflectivity = source.reflectivity; 38808 38809 this.clearCoat = source.clearCoat; 38810 this.clearCoatRoughness = source.clearCoatRoughness; 38811 38812 return this; 38813 38814 }; 38815 38816 /** 38817 * @author mrdoob / http://mrdoob.com/ 38818 * @author alteredq / http://alteredqualia.com/ 38819 * 38820 * parameters = { 38821 * color: <hex>, 38822 * specular: <hex>, 38823 * shininess: <float>, 38824 * opacity: <float>, 38825 * 38826 * map: new THREE.Texture( <Image> ), 38827 * 38828 * lightMap: new THREE.Texture( <Image> ), 38829 * lightMapIntensity: <float> 38830 * 38831 * aoMap: new THREE.Texture( <Image> ), 38832 * aoMapIntensity: <float> 38833 * 38834 * emissive: <hex>, 38835 * emissiveIntensity: <float> 38836 * emissiveMap: new THREE.Texture( <Image> ), 38837 * 38838 * bumpMap: new THREE.Texture( <Image> ), 38839 * bumpScale: <float>, 38840 * 38841 * normalMap: new THREE.Texture( <Image> ), 38842 * normalScale: <Vector2>,
38843 * 38844 * displacementMap: new THREE.Texture( <Image> ), 38845 * displacementScale: <float>, 38846 * displacementBias: <float>, 38847 * 38848 * specularMap: new THREE.Texture( <Image> ), 38849 * 38850 * alphaMap: new THREE.Texture( <Image> ), 38851 * 38852 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 38853 * combine: THREE.Multiply, 38854 * reflectivity: <float>, 38855 * refractionRatio: <float>, 38856 * 38857 * wireframe: <boolean>, 38858 * wireframeLinewidth: <float>, 38859 * 38860 * skinning: <bool>, 38861 * morphTargets: <bool>, 38862 * morphNormals: <bool> 38863 * } 38864 */ 38865 38866 function MeshPhongMaterial( parameters ) { 38867 38868 Material.call( this ); 38869 38870 this.type = 'MeshPhongMaterial'; 38871 38872 this.color = new Color( 0xffffff ); // diffuse 38873 this.specular = new Color( 0x111111 ); 38874 this.shininess = 30; 38875 38876 this.map = null; 38877 38878 this.lightMap = null; 38879 this.lightMapIntensity = 1.0; 38880 38881 this.aoMap = null; 38882 this.aoMapIntensity = 1.0; 38883 38884 this.emissive = new Color( 0x000000 ); 38885 this.emissiveIntensity = 1.0; 38886 this.emissiveMap = null; 38887 38888 this.bumpMap = null; 38889 this.bumpScale = 1; 38890 38891 this.normalMap = null; 38892 this.normalScale = new Vector2( 1, 1 ); 38893 38894 this.displacementMap = null; 38895 this.displacementScale = 1; 38896 this.displacementBias = 0; 38897 38898 this.specularMap = null; 38899 38900 this.alphaMap = null; 38901 38902 this.envMap = null; 38903 this.combine = MultiplyOperation; 38904 this.reflectivity = 1; 38905 this.refractionRatio = 0.98; 38906 38907 this.wireframe = false; 38908 this.wireframeLinewidth = 1; 38909 this.wireframeLinecap = 'round'; 38910 this.wireframeLinejoin = 'round'; 38911 38912 this.skinning = false; 38913 this.morphTargets = false; 38914 this.morphNormals = false; 38915 38916 this.setValues( parameters ); 38917 38918 } 38919 38920 MeshPhongMaterial.prototype = Object.create( Material.prototype ); 38921 MeshPhongMaterial.prototype.constructor = MeshPhongMaterial; 38922 38923 MeshPhongMaterial.prototype.isMeshPhongMaterial = true; 38924 38925 MeshPhongMaterial.prototype.copy = function ( source ) { 38926 38927 Material.prototype.copy.call( this, source ); 38928 38929 this.color.copy( source.color ); 38930 this.specular.copy( source.specular ); 38931 this.shininess = source.shininess; 38932 38933 this.map = source.map; 38934 38935 this.lightMap = source.lightMap; 38936 this.lightMapIntensity = source.lightMapIntensity; 38937 38938 this.aoMap = source.aoMap; 38939 this.aoMapIntensity = source.aoMapIntensity; 38940 38941 this.emissive.copy( source.emissive ); 38942 this.emissiveMap = source.emissiveMap; 38943 this.emissiveIntensity = source.emissiveIntensity; 38944 38945 this.bumpMap = source.bumpMap; 38946 this.bumpScale = source.bumpScale; 38947 38948 this.normalMap = source.normalMap; 38949 this.normalScale.copy( source.normalScale ); 38950 38951 this.displacementMap = source.displacementMap; 38952 this.displacementScale = source.displacementScale; 38953 this.displacementBias = source.displacementBias; 38954 38955 this.specularMap = source.specularMap; 38956 38957 this.alphaMap = source.alphaMap; 38958 38959 this.envMap = source.envMap; 38960 this.combine = source.combine; 38961 this.reflectivity = source.reflectivity; 38962 this.refractionRatio = source.refractionRatio; 38963 38964 this.wireframe = source.wireframe; 38965 this.wireframeLinewidth = source.wireframeLinewidth; 38966 this.wireframeLinecap = source.wireframeLinecap; 38967 this.wireframeLinejoin = source.wireframeLinejoin; 38968 38969 this.skinning = source.skinning; 38970 this.morphTargets = source.morphTargets; 38971 this.morphNormals = source.morphNormals; 38972 38973 return this; 38974 38975 }; 38976 38977 /** 38978 * @author takahirox / http://github.com/takahirox 38979 * 38980 * parameters = { 38981 * gradientMap: new THREE.Texture( <Image> ) 38982 * } 38983 */ 38984 38985 function MeshToonMaterial( parameters ) { 38986 38987 MeshPhongMaterial.call( this ); 38988 38989 this.defines = { 'TOON': '' }; 38990 38991 this.type = 'MeshToonMaterial'; 38992 38993 this.gradientMap = null; 38994 38995 this.setValues( parameters ); 38996 38997 } 38998 38999 MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype ); 39000 MeshToonMaterial.prototype.constructor = MeshToonMaterial; 39001 39002 MeshToonMaterial.prototype.isMeshToonMaterial = true; 39003 39004 MeshToonMaterial.prototype.copy = function ( source ) { 39005 39006 MeshPhongMaterial.prototype.copy.call( this, source ); 39007 39008 this.gradientMap = source.gradientMap; 39009 39010 return this; 39011 39012 }; 39013 39014 /** 39015 * @author mrdoob / http://mrdoob.com/ 39016 * @author WestLangley / http://github.com/WestLangley 39017 * 39018 * parameters = { 39019 * opacity: <float>, 39020 * 39021 * bumpMap: new THREE.Texture( <Image> ), 39022 * bumpScale: <float>, 39023 * 39024 * normalMap: new THREE.Texture( <Image> ), 39025 * normalScale: <Vector2>,
39026 * 39027 * displacementMap: new THREE.Texture( <Image> ), 39028 * displacementScale: <float>, 39029 * displacementBias: <float>, 39030 * 39031 * wireframe: <boolean>, 39032 * wireframeLinewidth: <float> 39033 * 39034 * skinning: <bool>, 39035 * morphTargets: <bool>, 39036 * morphNormals: <bool> 39037 * } 39038 */ 39039 39040 function MeshNormalMaterial( parameters ) { 39041 39042 Material.call( this ); 39043 39044 this.type = 'MeshNormalMaterial'; 39045 39046 this.bumpMap = null; 39047 this.bumpScale = 1; 39048 39049 this.normalMap = null; 39050 this.normalScale = new Vector2( 1, 1 ); 39051 39052 this.displacementMap = null; 39053 this.displacementScale = 1; 39054 this.displacementBias = 0; 39055 39056 this.wireframe = false; 39057 this.wireframeLinewidth = 1; 39058 39059 this.fog = false; 39060 this.lights = false; 39061 39062 this.skinning = false; 39063 this.morphTargets = false; 39064 this.morphNormals = false; 39065 39066 this.setValues( parameters ); 39067 39068 } 39069 39070 MeshNormalMaterial.prototype = Object.create( Material.prototype ); 39071 MeshNormalMaterial.prototype.constructor = MeshNormalMaterial; 39072 39073 MeshNormalMaterial.prototype.isMeshNormalMaterial = true; 39074 39075 MeshNormalMaterial.prototype.copy = function ( source ) { 39076 39077 Material.prototype.copy.call( this, source ); 39078 39079 this.bumpMap = source.bumpMap; 39080 this.bumpScale = source.bumpScale; 39081 39082 this.normalMap = source.normalMap; 39083 this.normalScale.copy( source.normalScale ); 39084 39085 this.displacementMap = source.displacementMap; 39086 this.displacementScale = source.displacementScale; 39087 this.displacementBias = source.displacementBias; 39088 39089 this.wireframe = source.wireframe; 39090 this.wireframeLinewidth = source.wireframeLinewidth; 39091 39092 this.skinning = source.skinning; 39093 this.morphTargets = source.morphTargets; 39094 this.morphNormals = source.morphNormals; 39095 39096 return this; 39097 39098 }; 39099 39100 /** 39101 * @author mrdoob / http://mrdoob.com/ 39102 * @author alteredq / http://alteredqualia.com/ 39103 * 39104 * parameters = { 39105 * color: <hex>, 39106 * opacity: <float>, 39107 * 39108 * map: new THREE.Texture( <Image> ), 39109 * 39110 * lightMap: new THREE.Texture( <Image> ), 39111 * lightMapIntensity: <float> 39112 * 39113 * aoMap: new THREE.Texture( <Image> ), 39114 * aoMapIntensity: <float> 39115 * 39116 * emissive: <hex>, 39117 * emissiveIntensity: <float> 39118 * emissiveMap: new THREE.Texture( <Image> ), 39119 * 39120 * specularMap: new THREE.Texture( <Image> ), 39121 * 39122 * alphaMap: new THREE.Texture( <Image> ), 39123 * 39124 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), 39125 * combine: THREE.Multiply, 39126 * reflectivity: <float>, 39127 * refractionRatio: <float>, 39128 * 39129 * wireframe: <boolean>, 39130 * wireframeLinewidth: <float>, 39131 * 39132 * skinning: <bool>, 39133 * morphTargets: <bool>, 39134 * morphNormals: <bool> 39135 * } 39136 */ 39137 39138 function MeshLambertMaterial( parameters ) { 39139 39140 Material.call( this ); 39141 39142 this.type = 'MeshLambertMaterial'; 39143 39144 this.color = new Color( 0xffffff ); // diffuse 39145 39146 this.map = null; 39147 39148 this.lightMap = null; 39149 this.lightMapIntensity = 1.0; 39150 39151 this.aoMap = null; 39152 this.aoMapIntensity = 1.0; 39153 39154 this.emissive = new Color( 0x000000 ); 39155 this.emissiveIntensity = 1.0; 39156 this.emissiveMap = null; 39157 39158 this.specularMap = null; 39159 39160 this.alphaMap = null; 39161 39162 this.envMap = null; 39163 this.combine = MultiplyOperation; 39164 this.reflectivity = 1; 39165 this.refractionRatio = 0.98; 39166 39167 this.wireframe = false; 39168 this.wireframeLinewidth = 1; 39169 this.wireframeLinecap = 'round'; 39170 this.wireframeLinejoin = 'round'; 39171 39172 this.skinning = false; 39173 this.morphTargets = false; 39174 this.morphNormals = false; 39175 39176 this.setValues( parameters ); 39177 39178 } 39179 39180 MeshLambertMaterial.prototype = Object.create( Material.prototype ); 39181 MeshLambertMaterial.prototype.constructor = MeshLambertMaterial; 39182 39183 MeshLambertMaterial.prototype.isMeshLambertMaterial = true; 39184 39185 MeshLambertMaterial.prototype.copy = function ( source ) { 39186 39187 Material.prototype.copy.call( this, source ); 39188 39189 this.color.copy( source.color ); 39190 39191 this.map = source.map; 39192 39193 this.lightMap = source.lightMap; 39194 this.lightMapIntensity = source.lightMapIntensity; 39195 39196 this.aoMap = source.aoMap; 39197 this.aoMapIntensity = source.aoMapIntensity; 39198 39199 this.emissive.copy( source.emissive ); 39200 this.emissiveMap = source.emissiveMap; 39201 this.emissiveIntensity = source.emissiveIntensity; 39202 39203 this.specularMap = source.specularMap; 39204 39205 this.alphaMap = source.alphaMap; 39206 39207 this.envMap = source.envMap; 39208 this.combine = source.combine; 39209 this.reflectivity = source.reflectivity; 39210 this.refractionRatio = source.refractionRatio; 39211 39212 this.wireframe = source.wireframe; 39213 this.wireframeLinewidth = source.wireframeLinewidth; 39214 this.wireframeLinecap = source.wireframeLinecap; 39215 this.wireframeLinejoin = source.wireframeLinejoin; 39216 39217 this.skinning = source.skinning; 39218 this.morphTargets = source.morphTargets; 39219 this.morphNormals = source.morphNormals; 39220 39221 return this; 39222 39223 }; 39224 39225 /** 39226 * @author alteredq / http://alteredqualia.com/ 39227 * 39228 * parameters = { 39229 * color: <hex>, 39230 * opacity: <float>, 39231 * 39232 * linewidth: <float>, 39233 * 39234 * scale: <float>, 39235 * dashSize: <float>, 39236 * gapSize: <float> 39237 * } 39238 */ 39239 39240 function LineDashedMaterial( parameters ) { 39241 39242 LineBasicMaterial.call( this ); 39243 39244 this.type = 'LineDashedMaterial'; 39245 39246 this.scale = 1; 39247 this.dashSize = 3; 39248 this.gapSize = 1; 39249 39250 this.setValues( parameters ); 39251 39252 } 39253 39254 LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype ); 39255 LineDashedMaterial.prototype.constructor = LineDashedMaterial; 39256 39257 LineDashedMaterial.prototype.isLineDashedMaterial = true; 39258 39259 LineDashedMaterial.prototype.copy = function ( source ) { 39260 39261 LineBasicMaterial.prototype.copy.call( this, source ); 39262 39263 this.scale = source.scale; 39264 this.dashSize = source.dashSize; 39265 this.gapSize = source.gapSize; 39266 39267 return this; 39268 39269 }; 39270 39271 39272 39273 var Materials = /*#__PURE__*/Object.freeze({ 39274 ShadowMaterial: ShadowMaterial, 39275 SpriteMaterial: SpriteMaterial, 39276 RawShaderMaterial: RawShaderMaterial, 39277 ShaderMaterial: ShaderMaterial, 39278 PointsMaterial: PointsMaterial, 39279 MeshPhysicalMaterial: MeshPhysicalMaterial, 39280 MeshStandardMaterial: MeshStandardMaterial, 39281 MeshPhongMaterial: MeshPhongMaterial, 39282 MeshToonMaterial: MeshToonMaterial, 39283 MeshNormalMaterial: MeshNormalMaterial, 39284 MeshLambertMaterial: MeshLambertMaterial, 39285 MeshDepthMaterial: MeshDepthMaterial, 39286 MeshDistanceMaterial: MeshDistanceMaterial, 39287 MeshBasicMaterial: MeshBasicMaterial, 39288 LineDashedMaterial: LineDashedMaterial, 39289 LineBasicMaterial: LineBasicMaterial, 39290 Material: Material 39291 }); 39292 39293 /** 39294 * @author mrdoob / http://mrdoob.com/ 39295 */ 39296 39297 var Cache = { 39298 39299 enabled: false, 39300 39301 files: {}, 39302 39303 add: function ( key, file ) { 39304 39305 if ( this.enabled === false ) return; 39306
vendor: 10,683 bytes, lines 39307-39876
39307 // console.log( 'THREE.Cache', 'Adding key:', key ); 39308 39309 this.files[ key ] = file; 39310 39311 }, 39312 39313 get: function ( key ) { 39314 39315 if ( this.enabled === false ) return; 39316 39317 // console.log( 'THREE.Cache', 'Checking key:', key ); 39318 39319 return this.files[ key ]; 39320 39321 }, 39322 39323 remove: function ( key ) { 39324 39325 delete this.files[ key ]; 39326 39327 }, 39328 39329 clear: function () { 39330 39331 this.files = {}; 39332 39333 } 39334 39335 }; 39336 39337 /** 39338 * @author mrdoob / http://mrdoob.com/ 39339 */ 39340 39341 function LoadingManager( onLoad, onProgress, onError ) { 39342 39343 var scope = this; 39344 39345 var isLoading = false; 39346 var itemsLoaded = 0; 39347 var itemsTotal = 0; 39348 var urlModifier = undefined; 39349 39350 this.onStart = undefined; 39351 this.onLoad = onLoad; 39352 this.onProgress = onProgress; 39353 this.onError = onError; 39354 39355 this.itemStart = function ( url ) { 39356 39357 itemsTotal ++; 39358 39359 if ( isLoading === false ) { 39360 39361 if ( scope.onStart !== undefined ) { 39362 39363 scope.onStart( url, itemsLoaded, itemsTotal ); 39364 39365 } 39366 39367 } 39368 39369 isLoading = true; 39370 39371 }; 39372 39373 this.itemEnd = function ( url ) { 39374 39375 itemsLoaded ++; 39376 39377 if ( scope.onProgress !== undefined ) { 39378 39379 scope.onProgress( url, itemsLoaded, itemsTotal ); 39380 39381 } 39382 39383 if ( itemsLoaded === itemsTotal ) { 39384 39385 isLoading = false; 39386 39387 if ( scope.onLoad !== undefined ) { 39388 39389 scope.onLoad(); 39390 39391 } 39392 39393 } 39394 39395 }; 39396 39397 this.itemError = function ( url ) { 39398 39399 if ( scope.onError !== undefined ) { 39400 39401 scope.onError( url ); 39402 39403 } 39404 39405 }; 39406 39407 this.resolveURL = function ( url ) { 39408 39409 if ( urlModifier ) { 39410 39411 return urlModifier( url ); 39412 39413 } 39414 39415 return url; 39416 39417 }; 39418 39419 this.setURLModifier = function ( transform ) { 39420 39421 urlModifier = transform; 39422 return this; 39423 39424 }; 39425 39426 } 39427 39428 var DefaultLoadingManager = new LoadingManager(); 39429 39430 /** 39431 * @author mrdoob / http://mrdoob.com/ 39432 */ 39433 39434 var loading = {}; 39435 39436 function FileLoader( manager ) { 39437 39438 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 39439 39440 } 39441 39442 Object.assign( FileLoader.prototype, { 39443 39444 load: function ( url, onLoad, onProgress, onError ) { 39445 39446 if ( url === undefined ) url = ''; 39447 39448 if ( this.path !== undefined ) url = this.path + url; 39449 39450 url = this.manager.resolveURL( url ); 39451 39452 var scope = this; 39453 39454 var cached = Cache.get( url ); 39455 39456 if ( cached !== undefined ) { 39457 39458 scope.manager.itemStart( url ); 39459 39460 setTimeout( function () { 39461 39462 if ( onLoad ) onLoad( cached ); 39463 39464 scope.manager.itemEnd( url ); 39465 39466 }, 0 ); 39467 39468 return cached; 39469 39470 } 39471 39472 // Check if request is duplicate 39473 39474 if ( loading[ url ] !== undefined ) { 39475 39476 loading[ url ].push( { 39477 39478 onLoad: onLoad, 39479 onProgress: onProgress, 39480 onError: onError 39481 39482 } ); 39483 39484 return; 39485 39486 } 39487 39488 // Check for data: URI 39489 var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; 39490 var dataUriRegexResult = url.match( dataUriRegex ); 39491 39492 // Safari can not handle Data URIs through XMLHttpRequest so process manually 39493 if ( dataUriRegexResult ) { 39494 39495 var mimeType = dataUriRegexResult[ 1 ]; 39496 var isBase64 = !! dataUriRegexResult[ 2 ]; 39497 var data = dataUriRegexResult[ 3 ]; 39498 39499 data = window.decodeURIComponent( data ); 39500 39501 if ( isBase64 ) data = window.atob( data ); 39502 39503 try { 39504 39505 var response; 39506 var responseType = ( this.responseType || '' ).toLowerCase(); 39507 39508 switch ( responseType ) { 39509 39510 case 'arraybuffer': 39511 case 'blob': 39512 39513 var view = new Uint8Array( data.length ); 39514 39515 for ( var i = 0; i < data.length; i ++ ) { 39516 39517 view[ i ] = data.charCodeAt( i ); 39518 39519 } 39520 39521 if ( responseType === 'blob' ) { 39522 39523 response = new Blob( [ view.buffer ], { type: mimeType } ); 39524 39525 } else { 39526 39527 response = view.buffer; 39528 39529 } 39530 39531 break; 39532 39533 case 'document': 39534 39535 var parser = new DOMParser(); 39536 response = parser.parseFromString( data, mimeType ); 39537 39538 break; 39539 39540 case 'json': 39541 39542 response = JSON.parse( data ); 39543 39544 break; 39545 39546 default: // 'text' or other 39547 39548 response = data; 39549 39550 break; 39551 39552 } 39553 39554 // Wait for next browser tick like standard XMLHttpRequest event dispatching does 39555 window.setTimeout( function () { 39556 39557 if ( onLoad ) onLoad( response ); 39558 39559 scope.manager.itemEnd( url ); 39560 39561 }, 0 ); 39562 39563 } catch ( error ) { 39564 39565 // Wait for next browser tick like standard XMLHttpRequest event dispatching does 39566 window.setTimeout( function () { 39567 39568 if ( onError ) onError( error ); 39569 39570 scope.manager.itemEnd( url ); 39571 scope.manager.itemError( url ); 39572 39573 }, 0 ); 39574 39575 } 39576 39577 } else { 39578 39579 // Initialise array for duplicate requests 39580 39581 loading[ url ] = []; 39582 39583 loading[ url ].push( { 39584 39585 onLoad: onLoad, 39586 onProgress: onProgress, 39587 onError: onError 39588 39589 } ); 39590 39591 var request = new XMLHttpRequest(); 39592 39593 request.open( 'GET', url, true ); 39594 39595 request.addEventListener( 'load', function ( event ) { 39596 39597 var response = this.response; 39598 39599 Cache.add( url, response ); 39600 39601 var callbacks = loading[ url ]; 39602 39603 delete loading[ url ]; 39604 39605 if ( this.status === 200 || this.status === 0 ) { 39606 39607 // Some browsers return HTTP Status 0 when using non-http protocol 39608 // e.g. 'file://' or 'data://'. Handle as success. 39609 39610 if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); 39611 39612 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 39613 39614 var callback = callbacks[ i ]; 39615 if ( callback.onLoad ) callback.onLoad( response ); 39616 39617 } 39618 39619 scope.manager.itemEnd( url ); 39620 39621 } else { 39622 39623 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 39624 39625 var callback = callbacks[ i ]; 39626 if ( callback.onError ) callback.onError( event ); 39627 39628 } 39629 39630 scope.manager.itemEnd( url ); 39631 scope.manager.itemError( url ); 39632 39633 } 39634 39635 }, false ); 39636 39637 request.addEventListener( 'progress', function ( event ) { 39638 39639 var callbacks = loading[ url ]; 39640 39641 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 39642 39643 var callback = callbacks[ i ]; 39644 if ( callback.onProgress ) callback.onProgress( event ); 39645 39646 } 39647 39648 }, false ); 39649 39650 request.addEventListener( 'error', function ( event ) { 39651 39652 var callbacks = loading[ url ]; 39653 39654 delete loading[ url ]; 39655 39656 for ( var i = 0, il = callbacks.length; i < il; i ++ ) { 39657 39658 var callback = callbacks[ i ]; 39659 if ( callback.onError ) callback.onError( event ); 39660 39661 } 39662 39663 scope.manager.itemEnd( url ); 39664 scope.manager.itemError( url ); 39665 39666 }, false ); 39667 39668 if ( this.responseType !== undefined ) request.responseType = this.responseType; 39669 if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; 39670 39671 if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); 39672 39673 for ( var header in this.requestHeader ) { 39674 39675 request.setRequestHeader( header, this.requestHeader[ header ] ); 39676 39677 } 39678 39679 request.send( null ); 39680 39681 } 39682 39683 scope.manager.itemStart( url ); 39684 39685 return request; 39686 39687 }, 39688 39689 setPath: function ( value ) { 39690 39691 this.path = value; 39692 return this; 39693 39694 }, 39695 39696 setResponseType: function ( value ) { 39697 39698 this.responseType = value; 39699 return this; 39700 39701 }, 39702 39703 setWithCredentials: function ( value ) { 39704 39705 this.withCredentials = value; 39706 return this; 39707 39708 }, 39709 39710 setMimeType: function ( value ) { 39711 39712 this.mimeType = value; 39713 return this; 39714 39715 }, 39716 39717 setRequestHeader: function ( value ) { 39718 39719 this.requestHeader = value; 39720 return this; 39721 39722 } 39723 39724 } ); 39725 39726 /** 39727 * @author mrdoob / http://mrdoob.com/ 39728 * 39729 * Abstract Base class to block based textures loader (dds, pvr, ...) 39730 */ 39731 39732 function CompressedTextureLoader( manager ) { 39733 39734 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 39735 39736 // override in sub classes 39737 this._parser = null; 39738 39739 } 39740 39741 Object.assign( CompressedTextureLoader.prototype, { 39742 39743 load: function ( url, onLoad, onProgress, onError ) { 39744 39745 var scope = this; 39746 39747 var images = []; 39748 39749 var texture = new CompressedTexture(); 39750 texture.image = images; 39751 39752 var loader = new FileLoader( this.manager ); 39753 loader.setPath( this.path ); 39754 loader.setResponseType( 'arraybuffer' ); 39755 39756 function loadTexture( i ) { 39757 39758 loader.load( url[ i ], function ( buffer ) { 39759 39760 var texDatas = scope._parser( buffer, true ); 39761 39762 images[ i ] = { 39763 width: texDatas.width, 39764 height: texDatas.height, 39765 format: texDatas.format, 39766 mipmaps: texDatas.mipmaps 39767 }; 39768 39769 loaded += 1; 39770 39771 if ( loaded === 6 ) { 39772 39773 if ( texDatas.mipmapCount === 1 ) 39774 texture.minFilter = LinearFilter; 39775 39776 texture.format = texDatas.format; 39777 texture.needsUpdate = true; 39778 39779 if ( onLoad ) onLoad( texture ); 39780 39781 } 39782 39783 }, onProgress, onError ); 39784 39785 } 39786 39787 if ( Array.isArray( url ) ) { 39788 39789 var loaded = 0; 39790 39791 for ( var i = 0, il = url.length; i < il; ++ i ) { 39792 39793 loadTexture( i ); 39794 39795 } 39796 39797 } else { 39798 39799 // compressed cubemap texture stored in a single DDS file 39800 39801 loader.load( url, function ( buffer ) { 39802 39803 var texDatas = scope._parser( buffer, true ); 39804 39805 if ( texDatas.isCubemap ) { 39806 39807 var faces = texDatas.mipmaps.length / texDatas.mipmapCount; 39808 39809 for ( var f = 0; f < faces; f ++ ) { 39810 39811 images[ f ] = { mipmaps: [] }; 39812 39813 for ( var i = 0; i < texDatas.mipmapCount; i ++ ) { 39814 39815 images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] ); 39816 images[ f ].format = texDatas.format; 39817 images[ f ].width = texDatas.width; 39818 images[ f ].height = texDatas.height; 39819 39820 } 39821 39822 } 39823 39824 } else { 39825 39826 texture.image.width = texDatas.width; 39827 texture.image.height = texDatas.height; 39828 texture.mipmaps = texDatas.mipmaps; 39829 39830 } 39831 39832 if ( texDatas.mipmapCount === 1 ) { 39833 39834 texture.minFilter = LinearFilter; 39835 39836 } 39837 39838 texture.format = texDatas.format; 39839 texture.needsUpdate = true; 39840 39841 if ( onLoad ) onLoad( texture ); 39842 39843 }, onProgress, onError ); 39844 39845 } 39846 39847 return texture; 39848 39849 }, 39850 39851 setPath: function ( value ) { 39852 39853 this.path = value; 39854 return this; 39855 39856 } 39857 39858 } ); 39859 39860 /** 39861 * @author Nikos M. / https://github.com/foo123/ 39862 * 39863 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) 39864 */ 39865 39866 function DataTextureLoader( manager ) { 39867 39868 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 39869 39870 // override in sub classes 39871 this._parser = null; 39872 39873 } 39874 39875 Object.assign( DataTextureLoader.prototype, { 39876
39877 load: function ( url, onLoad, onProgress, onError ) { 39878 39879 var scope = this; 39880 39881 var texture = new DataTexture(); 39882 39883 var loader = new FileLoader( this.manager ); 39884 loader.setResponseType( 'arraybuffer' ); 39885 39886 loader.load( url, function ( buffer ) { 39887 39888 var texData = scope._parser( buffer ); 39889 39890 if ( ! texData ) return; 39891 39892 if ( undefined !== texData.image ) { 39893 39894 texture.image = texData.image; 39895 39896 } else if ( undefined !== texData.data ) { 39897 39898 texture.image.width = texData.width; 39899 texture.image.height = texData.height; 39900 texture.image.data = texData.data; 39901 39902 } 39903 39904 texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping; 39905 texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping; 39906 39907 texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter; 39908 texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter; 39909 39910 texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1; 39911 39912 if ( undefined !== texData.format ) { 39913 39914 texture.format = texData.format; 39915 39916 } 39917 if ( undefined !== texData.type ) { 39918 39919 texture.type = texData.type; 39920 39921 } 39922 39923 if ( undefined !== texData.mipmaps ) { 39924 39925 texture.mipmaps = texData.mipmaps; 39926 39927 } 39928 39929 if ( 1 === texData.mipmapCount ) { 39930 39931 texture.minFilter = LinearFilter; 39932 39933 } 39934 39935 texture.needsUpdate = true; 39936 39937 if ( onLoad ) onLoad( texture, texData ); 39938 39939 }, onProgress, onError ); 39940 39941 39942 return texture; 39943 39944 } 39945 39946 } ); 39947 39948 /** 39949 * @author mrdoob / http://mrdoob.com/ 39950 */ 39951 39952 39953 function ImageLoader( manager ) { 39954 39955 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 39956 39957 } 39958 39959 Object.assign( ImageLoader.prototype, { 39960
vendor: 97,894 bytes, lines 39961-44526
39961 crossOrigin: 'Anonymous', 39962 39963 load: function ( url, onLoad, onProgress, onError ) { 39964 39965 if ( url === undefined ) url = ''; 39966 39967 if ( this.path !== undefined ) url = this.path + url; 39968 39969 url = this.manager.resolveURL( url ); 39970 39971 var scope = this; 39972 39973 var cached = Cache.get( url ); 39974 39975 if ( cached !== undefined ) { 39976 39977 scope.manager.itemStart( url ); 39978 39979 setTimeout( function () { 39980 39981 if ( onLoad ) onLoad( cached ); 39982 39983 scope.manager.itemEnd( url ); 39984 39985 }, 0 ); 39986 39987 return cached; 39988 39989 } 39990 39991 var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' ); 39992 39993 function onImageLoad() { 39994 39995 image.removeEventListener( 'load', onImageLoad, false ); 39996 image.removeEventListener( 'error', onImageError, false ); 39997 39998 Cache.add( url, this ); 39999 40000 if ( onLoad ) onLoad( this ); 40001 40002 scope.manager.itemEnd( url ); 40003 40004 } 40005 40006 function onImageError( event ) { 40007 40008 image.removeEventListener( 'load', onImageLoad, false ); 40009 image.removeEventListener( 'error', onImageError, false ); 40010 40011 if ( onError ) onError( event ); 40012 40013 scope.manager.itemEnd( url ); 40014 scope.manager.itemError( url ); 40015 40016 } 40017 40018 image.addEventListener( 'load', onImageLoad, false ); 40019 image.addEventListener( 'error', onImageError, false ); 40020 40021 if ( url.substr( 0, 5 ) !== 'data:' ) { 40022 40023 if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; 40024 40025 } 40026 40027 scope.manager.itemStart( url ); 40028 40029 image.src = url; 40030 40031 return image; 40032 40033 }, 40034 40035 setCrossOrigin: function ( value ) { 40036 40037 this.crossOrigin = value; 40038 return this; 40039 40040 }, 40041 40042 setPath: function ( value ) { 40043 40044 this.path = value; 40045 return this; 40046 40047 } 40048 40049 } ); 40050 40051 /** 40052 * @author mrdoob / http://mrdoob.com/ 40053 */ 40054 40055 40056 function CubeTextureLoader( manager ) { 40057 40058 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 40059 40060 } 40061 40062 Object.assign( CubeTextureLoader.prototype, { 40063 40064 crossOrigin: 'Anonymous', 40065 40066 load: function ( urls, onLoad, onProgress, onError ) { 40067 40068 var texture = new CubeTexture(); 40069 40070 var loader = new ImageLoader( this.manager ); 40071 loader.setCrossOrigin( this.crossOrigin ); 40072 loader.setPath( this.path ); 40073 40074 var loaded = 0; 40075 40076 function loadTexture( i ) { 40077 40078 loader.load( urls[ i ], function ( image ) { 40079 40080 texture.images[ i ] = image; 40081 40082 loaded ++; 40083 40084 if ( loaded === 6 ) { 40085 40086 texture.needsUpdate = true; 40087 40088 if ( onLoad ) onLoad( texture ); 40089 40090 } 40091 40092 }, undefined, onError ); 40093 40094 } 40095 40096 for ( var i = 0; i < urls.length; ++ i ) { 40097 40098 loadTexture( i ); 40099 40100 } 40101 40102 return texture; 40103 40104 }, 40105 40106 setCrossOrigin: function ( value ) { 40107 40108 this.crossOrigin = value; 40109 return this; 40110 40111 }, 40112 40113 setPath: function ( value ) { 40114 40115 this.path = value; 40116 return this; 40117 40118 } 40119 40120 } ); 40121 40122 /** 40123 * @author mrdoob / http://mrdoob.com/ 40124 */ 40125 40126 40127 function TextureLoader( manager ) { 40128 40129 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 40130 40131 } 40132 40133 Object.assign( TextureLoader.prototype, { 40134 40135 crossOrigin: 'Anonymous', 40136 40137 load: function ( url, onLoad, onProgress, onError ) { 40138 40139 var texture = new Texture(); 40140 40141 var loader = new ImageLoader( this.manager ); 40142 loader.setCrossOrigin( this.crossOrigin ); 40143 loader.setPath( this.path ); 40144 40145 loader.load( url, function ( image ) { 40146 40147 texture.image = image; 40148 40149 // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB. 40150 var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0; 40151 40152 texture.format = isJPEG ? RGBFormat : RGBAFormat; 40153 texture.needsUpdate = true; 40154 40155 if ( onLoad !== undefined ) { 40156 40157 onLoad( texture ); 40158 40159 } 40160 40161 }, onProgress, onError ); 40162 40163 return texture; 40164 40165 }, 40166 40167 setCrossOrigin: function ( value ) { 40168 40169 this.crossOrigin = value; 40170 return this; 40171 40172 }, 40173 40174 setPath: function ( value ) { 40175 40176 this.path = value; 40177 return this; 40178 40179 } 40180 40181 } ); 40182 40183 /** 40184 * @author zz85 / http://www.lab4games.net/zz85/blog 40185 * Extensible curve object 40186 * 40187 * Some common of curve methods: 40188 * .getPoint( t, optionalTarget ), .getTangent( t ) 40189 * .getPointAt( u, optionalTarget ), .getTangentAt( u ) 40190 * .getPoints(), .getSpacedPoints() 40191 * .getLength() 40192 * .updateArcLengths() 40193 * 40194 * This following curves inherit from THREE.Curve: 40195 * 40196 * -- 2D curves -- 40197 * THREE.ArcCurve 40198 * THREE.CubicBezierCurve 40199 * THREE.EllipseCurve 40200 * THREE.LineCurve 40201 * THREE.QuadraticBezierCurve 40202 * THREE.SplineCurve 40203 * 40204 * -- 3D curves -- 40205 * THREE.CatmullRomCurve3 40206 * THREE.CubicBezierCurve3 40207 * THREE.LineCurve3 40208 * THREE.QuadraticBezierCurve3 40209 * 40210 * A series of curves can be represented as a THREE.CurvePath. 40211 * 40212 **/ 40213 40214 /************************************************************** 40215 * Abstract Curve base class 40216 **************************************************************/ 40217 40218 function Curve() { 40219 40220 this.type = 'Curve'; 40221 40222 this.arcLengthDivisions = 200; 40223 40224 } 40225 40226 Object.assign( Curve.prototype, { 40227 40228 // Virtual base class method to overwrite and implement in subclasses 40229 // - t [0 .. 1] 40230 40231 getPoint: function ( /* t, optionalTarget */ ) { 40232 40233 console.warn( 'THREE.Curve: .getPoint() not implemented.' ); 40234 return null; 40235 40236 }, 40237 40238 // Get point at relative position in curve according to arc length 40239 // - u [0 .. 1] 40240 40241 getPointAt: function ( u, optionalTarget ) { 40242 40243 var t = this.getUtoTmapping( u ); 40244 return this.getPoint( t, optionalTarget ); 40245 40246 }, 40247 40248 // Get sequence of points using getPoint( t ) 40249 40250 getPoints: function ( divisions ) { 40251 40252 if ( divisions === undefined ) divisions = 5; 40253 40254 var points = []; 40255 40256 for ( var d = 0; d <= divisions; d ++ ) { 40257 40258 points.push( this.getPoint( d / divisions ) ); 40259 40260 } 40261 40262 return points; 40263 40264 }, 40265 40266 // Get sequence of points using getPointAt( u ) 40267 40268 getSpacedPoints: function ( divisions ) { 40269 40270 if ( divisions === undefined ) divisions = 5; 40271 40272 var points = []; 40273 40274 for ( var d = 0; d <= divisions; d ++ ) { 40275 40276 points.push( this.getPointAt( d / divisions ) ); 40277 40278 } 40279 40280 return points; 40281 40282 }, 40283 40284 // Get total curve arc length 40285 40286 getLength: function () { 40287 40288 var lengths = this.getLengths(); 40289 return lengths[ lengths.length - 1 ]; 40290 40291 }, 40292 40293 // Get list of cumulative segment lengths 40294 40295 getLengths: function ( divisions ) { 40296 40297 if ( divisions === undefined ) divisions = this.arcLengthDivisions; 40298 40299 if ( this.cacheArcLengths && 40300 ( this.cacheArcLengths.length === divisions + 1 ) && 40301 ! this.needsUpdate ) { 40302 40303 return this.cacheArcLengths; 40304 40305 } 40306 40307 this.needsUpdate = false; 40308 40309 var cache = []; 40310 var current, last = this.getPoint( 0 ); 40311 var p, sum = 0; 40312 40313 cache.push( 0 ); 40314 40315 for ( p = 1; p <= divisions; p ++ ) { 40316 40317 current = this.getPoint( p / divisions ); 40318 sum += current.distanceTo( last ); 40319 cache.push( sum ); 40320 last = current; 40321 40322 } 40323 40324 this.cacheArcLengths = cache; 40325 40326 return cache; // { sums: cache, sum: sum }; Sum is in the last element. 40327 40328 }, 40329 40330 updateArcLengths: function () { 40331 40332 this.needsUpdate = true; 40333 this.getLengths(); 40334 40335 }, 40336 40337 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant 40338 40339 getUtoTmapping: function ( u, distance ) { 40340 40341 var arcLengths = this.getLengths(); 40342 40343 var i = 0, il = arcLengths.length; 40344 40345 var targetArcLength; // The targeted u distance value to get 40346 40347 if ( distance ) { 40348 40349 targetArcLength = distance; 40350 40351 } else { 40352 40353 targetArcLength = u * arcLengths[ il - 1 ]; 40354 40355 } 40356 40357 // binary search for the index with largest value smaller than target u distance 40358 40359 var low = 0, high = il - 1, comparison; 40360 40361 while ( low <= high ) { 40362 40363 i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats 40364 40365 comparison = arcLengths[ i ] - targetArcLength; 40366 40367 if ( comparison < 0 ) { 40368 40369 low = i + 1; 40370 40371 } else if ( comparison > 0 ) { 40372 40373 high = i - 1; 40374 40375 } else { 40376 40377 high = i; 40378 break; 40379 40380 // DONE 40381 40382 } 40383 40384 } 40385 40386 i = high; 40387 40388 if ( arcLengths[ i ] === targetArcLength ) { 40389 40390 return i / ( il - 1 ); 40391 40392 } 40393 40394 // we could get finer grain at lengths, or use simple interpolation between two points 40395 40396 var lengthBefore = arcLengths[ i ]; 40397 var lengthAfter = arcLengths[ i + 1 ]; 40398 40399 var segmentLength = lengthAfter - lengthBefore; 40400 40401 // determine where we are between the 'before' and 'after' points 40402 40403 var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; 40404 40405 // add that fractional amount to t 40406 40407 var t = ( i + segmentFraction ) / ( il - 1 ); 40408 40409 return t; 40410 40411 }, 40412 40413 // Returns a unit vector tangent at t 40414 // In case any sub curve does not implement its tangent derivation, 40415 // 2 points a small delta apart will be used to find its gradient 40416 // which seems to give a reasonable approximation 40417 40418 getTangent: function ( t ) { 40419 40420 var delta = 0.0001; 40421 var t1 = t - delta; 40422 var t2 = t + delta; 40423 40424 // Capping in case of danger 40425 40426 if ( t1 < 0 ) t1 = 0; 40427 if ( t2 > 1 ) t2 = 1; 40428 40429 var pt1 = this.getPoint( t1 ); 40430 var pt2 = this.getPoint( t2 ); 40431 40432 var vec = pt2.clone().sub( pt1 ); 40433 return vec.normalize(); 40434 40435 }, 40436 40437 getTangentAt: function ( u ) { 40438 40439 var t = this.getUtoTmapping( u ); 40440 return this.getTangent( t ); 40441 40442 }, 40443 40444 computeFrenetFrames: function ( segments, closed ) { 40445 40446 // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf 40447 40448 var normal = new Vector3(); 40449 40450 var tangents = []; 40451 var normals = []; 40452 var binormals = []; 40453 40454 var vec = new Vector3(); 40455 var mat = new Matrix4(); 40456 40457 var i, u, theta; 40458 40459 // compute the tangent vectors for each segment on the curve 40460 40461 for ( i = 0; i <= segments; i ++ ) { 40462 40463 u = i / segments; 40464 40465 tangents[ i ] = this.getTangentAt( u ); 40466 tangents[ i ].normalize(); 40467 40468 } 40469 40470 // select an initial normal vector perpendicular to the first tangent vector, 40471 // and in the direction of the minimum tangent xyz component 40472 40473 normals[ 0 ] = new Vector3(); 40474 binormals[ 0 ] = new Vector3(); 40475 var min = Number.MAX_VALUE; 40476 var tx = Math.abs( tangents[ 0 ].x ); 40477 var ty = Math.abs( tangents[ 0 ].y ); 40478 var tz = Math.abs( tangents[ 0 ].z ); 40479 40480 if ( tx <= min ) { 40481 40482 min = tx; 40483 normal.set( 1, 0, 0 ); 40484 40485 } 40486 40487 if ( ty <= min ) { 40488 40489 min = ty; 40490 normal.set( 0, 1, 0 ); 40491 40492 } 40493 40494 if ( tz <= min ) { 40495 40496 normal.set( 0, 0, 1 ); 40497 40498 } 40499 40500 vec.crossVectors( tangents[ 0 ], normal ).normalize(); 40501 40502 normals[ 0 ].crossVectors( tangents[ 0 ], vec ); 40503 binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); 40504 40505 40506 // compute the slowly-varying normal and binormal vectors for each segment on the curve 40507 40508 for ( i = 1; i <= segments; i ++ ) { 40509 40510 normals[ i ] = normals[ i - 1 ].clone(); 40511 40512 binormals[ i ] = binormals[ i - 1 ].clone(); 40513 40514 vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); 40515 40516 if ( vec.length() > Number.EPSILON ) { 40517 40518 vec.normalize(); 40519 40520 theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors 40521 40522 normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); 40523 40524 } 40525 40526 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); 40527 40528 } 40529 40530 // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same 40531 40532 if ( closed === true ) { 40533 40534 theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); 40535 theta /= segments; 40536 40537 if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { 40538 40539 theta = - theta; 40540 40541 } 40542 40543 for ( i = 1; i <= segments; i ++ ) { 40544 40545 // twist a little... 40546 normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); 40547 binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); 40548 40549 } 40550 40551 } 40552 40553 return { 40554 tangents: tangents, 40555 normals: normals, 40556 binormals: binormals 40557 }; 40558 40559 }, 40560 40561 clone: function () { 40562 40563 return new this.constructor().copy( this ); 40564 40565 }, 40566 40567 copy: function ( source ) { 40568 40569 this.arcLengthDivisions = source.arcLengthDivisions; 40570 40571 return this; 40572 40573 }, 40574 40575 toJSON: function () { 40576 40577 var data = { 40578 metadata: { 40579 version: 4.5, 40580 type: 'Curve', 40581 generator: 'Curve.toJSON' 40582 } 40583 }; 40584 40585 data.arcLengthDivisions = this.arcLengthDivisions; 40586 data.type = this.type; 40587 40588 return data; 40589 40590 }, 40591 40592 fromJSON: function ( json ) { 40593 40594 this.arcLengthDivisions = json.arcLengthDivisions; 40595 40596 return this; 40597 40598 } 40599 40600 } ); 40601 40602 function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 40603 40604 Curve.call( this ); 40605 40606 this.type = 'EllipseCurve'; 40607 40608 this.aX = aX || 0; 40609 this.aY = aY || 0; 40610 40611 this.xRadius = xRadius || 1; 40612 this.yRadius = yRadius || 1; 40613 40614 this.aStartAngle = aStartAngle || 0; 40615 this.aEndAngle = aEndAngle || 2 * Math.PI; 40616 40617 this.aClockwise = aClockwise || false; 40618 40619 this.aRotation = aRotation || 0; 40620 40621 } 40622 40623 EllipseCurve.prototype = Object.create( Curve.prototype ); 40624 EllipseCurve.prototype.constructor = EllipseCurve; 40625 40626 EllipseCurve.prototype.isEllipseCurve = true; 40627 40628 EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) { 40629 40630 var point = optionalTarget || new Vector2(); 40631 40632 var twoPi = Math.PI * 2; 40633 var deltaAngle = this.aEndAngle - this.aStartAngle; 40634 var samePoints = Math.abs( deltaAngle ) < Number.EPSILON; 40635 40636 // ensures that deltaAngle is 0 .. 2 PI 40637 while ( deltaAngle < 0 ) deltaAngle += twoPi; 40638 while ( deltaAngle > twoPi ) deltaAngle -= twoPi; 40639 40640 if ( deltaAngle < Number.EPSILON ) { 40641 40642 if ( samePoints ) { 40643 40644 deltaAngle = 0; 40645 40646 } else { 40647 40648 deltaAngle = twoPi; 40649 40650 } 40651 40652 } 40653 40654 if ( this.aClockwise === true && ! samePoints ) { 40655 40656 if ( deltaAngle === twoPi ) { 40657 40658 deltaAngle = - twoPi; 40659 40660 } else { 40661 40662 deltaAngle = deltaAngle - twoPi; 40663 40664 } 40665 40666 } 40667 40668 var angle = this.aStartAngle + t * deltaAngle; 40669 var x = this.aX + this.xRadius * Math.cos( angle ); 40670 var y = this.aY + this.yRadius * Math.sin( angle ); 40671 40672 if ( this.aRotation !== 0 ) { 40673 40674 var cos = Math.cos( this.aRotation ); 40675 var sin = Math.sin( this.aRotation ); 40676 40677 var tx = x - this.aX; 40678 var ty = y - this.aY; 40679 40680 // Rotate the point about the center of the ellipse. 40681 x = tx * cos - ty * sin + this.aX; 40682 y = tx * sin + ty * cos + this.aY; 40683 40684 } 40685 40686 return point.set( x, y ); 40687 40688 }; 40689 40690 EllipseCurve.prototype.copy = function ( source ) { 40691 40692 Curve.prototype.copy.call( this, source ); 40693 40694 this.aX = source.aX; 40695 this.aY = source.aY; 40696 40697 this.xRadius = source.xRadius; 40698 this.yRadius = source.yRadius; 40699 40700 this.aStartAngle = source.aStartAngle; 40701 this.aEndAngle = source.aEndAngle; 40702 40703 this.aClockwise = source.aClockwise; 40704 40705 this.aRotation = source.aRotation; 40706 40707 return this; 40708 40709 }; 40710 40711 40712 EllipseCurve.prototype.toJSON = function () { 40713 40714 var data = Curve.prototype.toJSON.call( this ); 40715 40716 data.aX = this.aX; 40717 data.aY = this.aY; 40718 40719 data.xRadius = this.xRadius; 40720 data.yRadius = this.yRadius; 40721 40722 data.aStartAngle = this.aStartAngle; 40723 data.aEndAngle = this.aEndAngle; 40724 40725 data.aClockwise = this.aClockwise; 40726 40727 data.aRotation = this.aRotation; 40728 40729 return data; 40730 40731 }; 40732 40733 EllipseCurve.prototype.fromJSON = function ( json ) { 40734 40735 Curve.prototype.fromJSON.call( this, json ); 40736 40737 this.aX = json.aX; 40738 this.aY = json.aY; 40739 40740 this.xRadius = json.xRadius; 40741 this.yRadius = json.yRadius; 40742 40743 this.aStartAngle = json.aStartAngle; 40744 this.aEndAngle = json.aEndAngle; 40745 40746 this.aClockwise = json.aClockwise; 40747 40748 this.aRotation = json.aRotation; 40749 40750 return this; 40751 40752 }; 40753 40754 function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 40755 40756 EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); 40757 40758 this.type = 'ArcCurve'; 40759 40760 } 40761 40762 ArcCurve.prototype = Object.create( EllipseCurve.prototype ); 40763 ArcCurve.prototype.constructor = ArcCurve; 40764 40765 ArcCurve.prototype.isArcCurve = true; 40766 40767 /** 40768 * @author zz85 https://github.com/zz85 40769 * 40770 * Centripetal CatmullRom Curve - which is useful for avoiding 40771 * cusps and self-intersections in non-uniform catmull rom curves. 40772 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf 40773 * 40774 * curve.type accepts centripetal(default), chordal and catmullrom 40775 * curve.tension is used for catmullrom which defaults to 0.5 40776 */ 40777 40778 40779 /* 40780 Based on an optimized c++ solution in 40781 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ 40782 - http://ideone.com/NoEbVM 40783 40784 This CubicPoly class could be used for reusing some variables and calculations, 40785 but for three.js curve use, it could be possible inlined and flatten into a single function call 40786 which can be placed in CurveUtils. 40787 */ 40788 40789 function CubicPoly() { 40790 40791 var c0 = 0, c1 = 0, c2 = 0, c3 = 0; 40792 40793 /* 40794 * Compute coefficients for a cubic polynomial 40795 * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 40796 * such that 40797 * p(0) = x0, p(1) = x1 40798 * and 40799 * p'(0) = t0, p'(1) = t1. 40800 */ 40801 function init( x0, x1, t0, t1 ) { 40802 40803 c0 = x0; 40804 c1 = t0; 40805 c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; 40806 c3 = 2 * x0 - 2 * x1 + t0 + t1; 40807 40808 } 40809 40810 return { 40811 40812 initCatmullRom: function ( x0, x1, x2, x3, tension ) { 40813 40814 init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); 40815 40816 }, 40817 40818 initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) { 40819 40820 // compute tangents when parameterized in [t1,t2] 40821 var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1; 40822 var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2; 40823 40824 // rescale tangents for parametrization in [0,1] 40825 t1 *= dt1; 40826 t2 *= dt1; 40827 40828 init( x1, x2, t1, t2 ); 40829 40830 }, 40831 40832 calc: function ( t ) { 40833 40834 var t2 = t * t; 40835 var t3 = t2 * t; 40836 return c0 + c1 * t + c2 * t2 + c3 * t3; 40837 40838 } 40839 40840 }; 40841 40842 } 40843 40844 // 40845 40846 var tmp = new Vector3(); 40847 var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly(); 40848 40849 function CatmullRomCurve3( points, closed, curveType, tension ) { 40850 40851 Curve.call( this ); 40852 40853 this.type = 'CatmullRomCurve3'; 40854 40855 this.points = points || []; 40856 this.closed = closed || false; 40857 this.curveType = curveType || 'centripetal'; 40858 this.tension = tension || 0.5; 40859 40860 } 40861 40862 CatmullRomCurve3.prototype = Object.create( Curve.prototype ); 40863 CatmullRomCurve3.prototype.constructor = CatmullRomCurve3; 40864 40865 CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; 40866 40867 CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) { 40868 40869 var point = optionalTarget || new Vector3(); 40870 40871 var points = this.points; 40872 var l = points.length; 40873 40874 var p = ( l - ( this.closed ? 0 : 1 ) ) * t; 40875 var intPoint = Math.floor( p ); 40876 var weight = p - intPoint; 40877 40878 if ( this.closed ) { 40879 40880 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l; 40881 40882 } else if ( weight === 0 && intPoint === l - 1 ) { 40883 40884 intPoint = l - 2; 40885 weight = 1; 40886 40887 } 40888 40889 var p0, p1, p2, p3; // 4 points 40890 40891 if ( this.closed || intPoint > 0 ) { 40892 40893 p0 = points[ ( intPoint - 1 ) % l ]; 40894 40895 } else { 40896 40897 // extrapolate first point 40898 tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] ); 40899 p0 = tmp; 40900 40901 } 40902 40903 p1 = points[ intPoint % l ]; 40904 p2 = points[ ( intPoint + 1 ) % l ]; 40905 40906 if ( this.closed || intPoint + 2 < l ) { 40907 40908 p3 = points[ ( intPoint + 2 ) % l ]; 40909 40910 } else { 40911 40912 // extrapolate last point 40913 tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); 40914 p3 = tmp; 40915 40916 } 40917 40918 if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { 40919 40920 // init Centripetal / Chordal Catmull-Rom 40921 var pow = this.curveType === 'chordal' ? 0.5 : 0.25; 40922 var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow ); 40923 var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow ); 40924 var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow ); 40925 40926 // safety check for repeated points 40927 if ( dt1 < 1e-4 ) dt1 = 1.0; 40928 if ( dt0 < 1e-4 ) dt0 = dt1; 40929 if ( dt2 < 1e-4 ) dt2 = dt1; 40930 40931 px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); 40932 py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); 40933 pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); 40934 40935 } else if ( this.curveType === 'catmullrom' ) { 40936 40937 px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); 40938 py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); 40939 pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); 40940 40941 } 40942 40943 point.set( 40944 px.calc( weight ), 40945 py.calc( weight ), 40946 pz.calc( weight ) 40947 ); 40948 40949 return point; 40950 40951 }; 40952 40953 CatmullRomCurve3.prototype.copy = function ( source ) { 40954 40955 Curve.prototype.copy.call( this, source ); 40956 40957 this.points = []; 40958 40959 for ( var i = 0, l = source.points.length; i < l; i ++ ) { 40960 40961 var point = source.points[ i ]; 40962 40963 this.points.push( point.clone() ); 40964 40965 } 40966 40967 this.closed = source.closed; 40968 this.curveType = source.curveType; 40969 this.tension = source.tension; 40970 40971 return this; 40972 40973 }; 40974 40975 CatmullRomCurve3.prototype.toJSON = function () { 40976 40977 var data = Curve.prototype.toJSON.call( this ); 40978 40979 data.points = []; 40980 40981 for ( var i = 0, l = this.points.length; i < l; i ++ ) { 40982 40983 var point = this.points[ i ]; 40984 data.points.push( point.toArray() ); 40985 40986 } 40987 40988 data.closed = this.closed; 40989 data.curveType = this.curveType; 40990 data.tension = this.tension; 40991 40992 return data; 40993 40994 }; 40995 40996 CatmullRomCurve3.prototype.fromJSON = function ( json ) { 40997 40998 Curve.prototype.fromJSON.call( this, json ); 40999 41000 this.points = []; 41001 41002 for ( var i = 0, l = json.points.length; i < l; i ++ ) { 41003 41004 var point = json.points[ i ]; 41005 this.points.push( new Vector3().fromArray( point ) ); 41006 41007 } 41008 41009 this.closed = json.closed; 41010 this.curveType = json.curveType; 41011 this.tension = json.tension; 41012 41013 return this; 41014 41015 }; 41016 41017 /** 41018 * @author zz85 / http://www.lab4games.net/zz85/blog 41019 * 41020 * Bezier Curves formulas obtained from 41021 * http://en.wikipedia.org/wiki/Bézier_curve 41022 */ 41023 41024 function CatmullRom( t, p0, p1, p2, p3 ) { 41025 41026 var v0 = ( p2 - p0 ) * 0.5; 41027 var v1 = ( p3 - p1 ) * 0.5; 41028 var t2 = t * t; 41029 var t3 = t * t2; 41030 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1; 41031 41032 } 41033 41034 // 41035 41036 function QuadraticBezierP0( t, p ) { 41037 41038 var k = 1 - t; 41039 return k * k * p; 41040 41041 } 41042 41043 function QuadraticBezierP1( t, p ) { 41044 41045 return 2 * ( 1 - t ) * t * p; 41046 41047 } 41048 41049 function QuadraticBezierP2( t, p ) { 41050 41051 return t * t * p; 41052 41053 } 41054 41055 function QuadraticBezier( t, p0, p1, p2 ) { 41056 41057 return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) + 41058 QuadraticBezierP2( t, p2 ); 41059 41060 } 41061 41062 // 41063 41064 function CubicBezierP0( t, p ) { 41065 41066 var k = 1 - t; 41067 return k * k * k * p; 41068 41069 } 41070 41071 function CubicBezierP1( t, p ) { 41072 41073 var k = 1 - t; 41074 return 3 * k * k * t * p; 41075 41076 } 41077 41078 function CubicBezierP2( t, p ) { 41079 41080 return 3 * ( 1 - t ) * t * t * p; 41081 41082 } 41083 41084 function CubicBezierP3( t, p ) { 41085 41086 return t * t * t * p; 41087 41088 } 41089 41090 function CubicBezier( t, p0, p1, p2, p3 ) { 41091 41092 return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) + 41093 CubicBezierP3( t, p3 ); 41094 41095 } 41096 41097 function CubicBezierCurve( v0, v1, v2, v3 ) { 41098 41099 Curve.call( this ); 41100 41101 this.type = 'CubicBezierCurve'; 41102 41103 this.v0 = v0 || new Vector2(); 41104 this.v1 = v1 || new Vector2(); 41105 this.v2 = v2 || new Vector2(); 41106 this.v3 = v3 || new Vector2(); 41107 41108 } 41109 41110 CubicBezierCurve.prototype = Object.create( Curve.prototype ); 41111 CubicBezierCurve.prototype.constructor = CubicBezierCurve; 41112 41113 CubicBezierCurve.prototype.isCubicBezierCurve = true; 41114 41115 CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { 41116 41117 var point = optionalTarget || new Vector2(); 41118 41119 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; 41120 41121 point.set( 41122 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), 41123 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ) 41124 ); 41125 41126 return point; 41127 41128 }; 41129 41130 CubicBezierCurve.prototype.copy = function ( source ) { 41131 41132 Curve.prototype.copy.call( this, source ); 41133 41134 this.v0.copy( source.v0 ); 41135 this.v1.copy( source.v1 ); 41136 this.v2.copy( source.v2 ); 41137 this.v3.copy( source.v3 ); 41138 41139 return this; 41140 41141 }; 41142 41143 CubicBezierCurve.prototype.toJSON = function () { 41144 41145 var data = Curve.prototype.toJSON.call( this ); 41146 41147 data.v0 = this.v0.toArray(); 41148 data.v1 = this.v1.toArray(); 41149 data.v2 = this.v2.toArray(); 41150 data.v3 = this.v3.toArray(); 41151 41152 return data; 41153 41154 }; 41155 41156 CubicBezierCurve.prototype.fromJSON = function ( json ) { 41157 41158 Curve.prototype.fromJSON.call( this, json ); 41159 41160 this.v0.fromArray( json.v0 ); 41161 this.v1.fromArray( json.v1 ); 41162 this.v2.fromArray( json.v2 ); 41163 this.v3.fromArray( json.v3 ); 41164 41165 return this; 41166 41167 }; 41168 41169 function CubicBezierCurve3( v0, v1, v2, v3 ) { 41170 41171 Curve.call( this ); 41172 41173 this.type = 'CubicBezierCurve3'; 41174 41175 this.v0 = v0 || new Vector3(); 41176 this.v1 = v1 || new Vector3(); 41177 this.v2 = v2 || new Vector3(); 41178 this.v3 = v3 || new Vector3(); 41179 41180 } 41181 41182 CubicBezierCurve3.prototype = Object.create( Curve.prototype ); 41183 CubicBezierCurve3.prototype.constructor = CubicBezierCurve3; 41184 41185 CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; 41186 41187 CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { 41188 41189 var point = optionalTarget || new Vector3(); 41190 41191 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; 41192 41193 point.set( 41194 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), 41195 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ), 41196 CubicBezier( t, v0.z, v1.z, v2.z, v3.z ) 41197 ); 41198 41199 return point; 41200 41201 }; 41202 41203 CubicBezierCurve3.prototype.copy = function ( source ) { 41204 41205 Curve.prototype.copy.call( this, source ); 41206 41207 this.v0.copy( source.v0 ); 41208 this.v1.copy( source.v1 ); 41209 this.v2.copy( source.v2 ); 41210 this.v3.copy( source.v3 ); 41211 41212 return this; 41213 41214 }; 41215 41216 CubicBezierCurve3.prototype.toJSON = function () { 41217 41218 var data = Curve.prototype.toJSON.call( this ); 41219 41220 data.v0 = this.v0.toArray(); 41221 data.v1 = this.v1.toArray(); 41222 data.v2 = this.v2.toArray(); 41223 data.v3 = this.v3.toArray(); 41224 41225 return data; 41226 41227 }; 41228 41229 CubicBezierCurve3.prototype.fromJSON = function ( json ) { 41230 41231 Curve.prototype.fromJSON.call( this, json ); 41232 41233 this.v0.fromArray( json.v0 ); 41234 this.v1.fromArray( json.v1 ); 41235 this.v2.fromArray( json.v2 ); 41236 this.v3.fromArray( json.v3 ); 41237 41238 return this; 41239 41240 }; 41241 41242 function LineCurve( v1, v2 ) { 41243 41244 Curve.call( this ); 41245 41246 this.type = 'LineCurve'; 41247 41248 this.v1 = v1 || new Vector2(); 41249 this.v2 = v2 || new Vector2(); 41250 41251 } 41252 41253 LineCurve.prototype = Object.create( Curve.prototype ); 41254 LineCurve.prototype.constructor = LineCurve; 41255 41256 LineCurve.prototype.isLineCurve = true; 41257 41258 LineCurve.prototype.getPoint = function ( t, optionalTarget ) { 41259 41260 var point = optionalTarget || new Vector2(); 41261 41262 if ( t === 1 ) { 41263 41264 point.copy( this.v2 ); 41265 41266 } else { 41267 41268 point.copy( this.v2 ).sub( this.v1 ); 41269 point.multiplyScalar( t ).add( this.v1 ); 41270 41271 } 41272 41273 return point; 41274 41275 }; 41276 41277 // Line curve is linear, so we can overwrite default getPointAt 41278 41279 LineCurve.prototype.getPointAt = function ( u, optionalTarget ) { 41280 41281 return this.getPoint( u, optionalTarget ); 41282 41283 }; 41284 41285 LineCurve.prototype.getTangent = function ( /* t */ ) { 41286 41287 var tangent = this.v2.clone().sub( this.v1 ); 41288 41289 return tangent.normalize(); 41290 41291 }; 41292 41293 LineCurve.prototype.copy = function ( source ) { 41294 41295 Curve.prototype.copy.call( this, source ); 41296 41297 this.v1.copy( source.v1 ); 41298 this.v2.copy( source.v2 ); 41299 41300 return this; 41301 41302 }; 41303 41304 LineCurve.prototype.toJSON = function () { 41305 41306 var data = Curve.prototype.toJSON.call( this ); 41307 41308 data.v1 = this.v1.toArray(); 41309 data.v2 = this.v2.toArray(); 41310 41311 return data; 41312 41313 }; 41314 41315 LineCurve.prototype.fromJSON = function ( json ) { 41316 41317 Curve.prototype.fromJSON.call( this, json ); 41318 41319 this.v1.fromArray( json.v1 ); 41320 this.v2.fromArray( json.v2 ); 41321 41322 return this; 41323 41324 }; 41325 41326 function LineCurve3( v1, v2 ) { 41327 41328 Curve.call( this ); 41329 41330 this.type = 'LineCurve3'; 41331 41332 this.v1 = v1 || new Vector3(); 41333 this.v2 = v2 || new Vector3(); 41334 41335 } 41336 41337 LineCurve3.prototype = Object.create( Curve.prototype ); 41338 LineCurve3.prototype.constructor = LineCurve3; 41339 41340 LineCurve3.prototype.isLineCurve3 = true; 41341 41342 LineCurve3.prototype.getPoint = function ( t, optionalTarget ) { 41343 41344 var point = optionalTarget || new Vector3(); 41345 41346 if ( t === 1 ) { 41347 41348 point.copy( this.v2 ); 41349 41350 } else { 41351 41352 point.copy( this.v2 ).sub( this.v1 ); 41353 point.multiplyScalar( t ).add( this.v1 ); 41354 41355 } 41356 41357 return point; 41358 41359 }; 41360 41361 // Line curve is linear, so we can overwrite default getPointAt 41362 41363 LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) { 41364 41365 return this.getPoint( u, optionalTarget ); 41366 41367 }; 41368 41369 LineCurve3.prototype.copy = function ( source ) { 41370 41371 Curve.prototype.copy.call( this, source ); 41372 41373 this.v1.copy( source.v1 ); 41374 this.v2.copy( source.v2 ); 41375 41376 return this; 41377 41378 }; 41379 41380 LineCurve3.prototype.toJSON = function () { 41381 41382 var data = Curve.prototype.toJSON.call( this ); 41383 41384 data.v1 = this.v1.toArray(); 41385 data.v2 = this.v2.toArray(); 41386 41387 return data; 41388 41389 }; 41390 41391 LineCurve3.prototype.fromJSON = function ( json ) { 41392 41393 Curve.prototype.fromJSON.call( this, json ); 41394 41395 this.v1.fromArray( json.v1 ); 41396 this.v2.fromArray( json.v2 ); 41397 41398 return this; 41399 41400 }; 41401 41402 function QuadraticBezierCurve( v0, v1, v2 ) { 41403 41404 Curve.call( this ); 41405 41406 this.type = 'QuadraticBezierCurve'; 41407 41408 this.v0 = v0 || new Vector2(); 41409 this.v1 = v1 || new Vector2(); 41410 this.v2 = v2 || new Vector2(); 41411 41412 } 41413 41414 QuadraticBezierCurve.prototype = Object.create( Curve.prototype ); 41415 QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve; 41416 41417 QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; 41418 41419 QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { 41420 41421 var point = optionalTarget || new Vector2(); 41422 41423 var v0 = this.v0, v1 = this.v1, v2 = this.v2; 41424 41425 point.set( 41426 QuadraticBezier( t, v0.x, v1.x, v2.x ), 41427 QuadraticBezier( t, v0.y, v1.y, v2.y ) 41428 ); 41429 41430 return point; 41431 41432 }; 41433 41434 QuadraticBezierCurve.prototype.copy = function ( source ) { 41435 41436 Curve.prototype.copy.call( this, source ); 41437 41438 this.v0.copy( source.v0 ); 41439 this.v1.copy( source.v1 ); 41440 this.v2.copy( source.v2 ); 41441 41442 return this; 41443 41444 }; 41445 41446 QuadraticBezierCurve.prototype.toJSON = function () { 41447 41448 var data = Curve.prototype.toJSON.call( this ); 41449 41450 data.v0 = this.v0.toArray(); 41451 data.v1 = this.v1.toArray(); 41452 data.v2 = this.v2.toArray(); 41453 41454 return data; 41455 41456 }; 41457 41458 QuadraticBezierCurve.prototype.fromJSON = function ( json ) { 41459 41460 Curve.prototype.fromJSON.call( this, json ); 41461 41462 this.v0.fromArray( json.v0 ); 41463 this.v1.fromArray( json.v1 ); 41464 this.v2.fromArray( json.v2 ); 41465 41466 return this; 41467 41468 }; 41469 41470 function QuadraticBezierCurve3( v0, v1, v2 ) { 41471 41472 Curve.call( this ); 41473 41474 this.type = 'QuadraticBezierCurve3'; 41475 41476 this.v0 = v0 || new Vector3(); 41477 this.v1 = v1 || new Vector3(); 41478 this.v2 = v2 || new Vector3(); 41479 41480 } 41481 41482 QuadraticBezierCurve3.prototype = Object.create( Curve.prototype ); 41483 QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3; 41484 41485 QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; 41486 41487 QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { 41488 41489 var point = optionalTarget || new Vector3(); 41490 41491 var v0 = this.v0, v1 = this.v1, v2 = this.v2; 41492 41493 point.set( 41494 QuadraticBezier( t, v0.x, v1.x, v2.x ), 41495 QuadraticBezier( t, v0.y, v1.y, v2.y ), 41496 QuadraticBezier( t, v0.z, v1.z, v2.z ) 41497 ); 41498 41499 return point; 41500 41501 }; 41502 41503 QuadraticBezierCurve3.prototype.copy = function ( source ) { 41504 41505 Curve.prototype.copy.call( this, source ); 41506 41507 this.v0.copy( source.v0 ); 41508 this.v1.copy( source.v1 ); 41509 this.v2.copy( source.v2 ); 41510 41511 return this; 41512 41513 }; 41514 41515 QuadraticBezierCurve3.prototype.toJSON = function () { 41516 41517 var data = Curve.prototype.toJSON.call( this ); 41518 41519 data.v0 = this.v0.toArray(); 41520 data.v1 = this.v1.toArray(); 41521 data.v2 = this.v2.toArray(); 41522 41523 return data; 41524 41525 }; 41526 41527 QuadraticBezierCurve3.prototype.fromJSON = function ( json ) { 41528 41529 Curve.prototype.fromJSON.call( this, json ); 41530 41531 this.v0.fromArray( json.v0 ); 41532 this.v1.fromArray( json.v1 ); 41533 this.v2.fromArray( json.v2 ); 41534 41535 return this; 41536 41537 }; 41538 41539 function SplineCurve( points /* array of Vector2 */ ) { 41540 41541 Curve.call( this ); 41542 41543 this.type = 'SplineCurve'; 41544 41545 this.points = points || []; 41546 41547 } 41548 41549 SplineCurve.prototype = Object.create( Curve.prototype ); 41550 SplineCurve.prototype.constructor = SplineCurve; 41551 41552 SplineCurve.prototype.isSplineCurve = true; 41553 41554 SplineCurve.prototype.getPoint = function ( t, optionalTarget ) { 41555 41556 var point = optionalTarget || new Vector2(); 41557 41558 var points = this.points; 41559 var p = ( points.length - 1 ) * t; 41560 41561 var intPoint = Math.floor( p ); 41562 var weight = p - intPoint; 41563 41564 var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; 41565 var p1 = points[ intPoint ]; 41566 var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; 41567 var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; 41568 41569 point.set( 41570 CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), 41571 CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) 41572 ); 41573 41574 return point; 41575 41576 }; 41577 41578 SplineCurve.prototype.copy = function ( source ) { 41579 41580 Curve.prototype.copy.call( this, source ); 41581 41582 this.points = []; 41583 41584 for ( var i = 0, l = source.points.length; i < l; i ++ ) { 41585 41586 var point = source.points[ i ]; 41587 41588 this.points.push( point.clone() ); 41589 41590 } 41591 41592 return this; 41593 41594 }; 41595 41596 SplineCurve.prototype.toJSON = function () { 41597 41598 var data = Curve.prototype.toJSON.call( this ); 41599 41600 data.points = []; 41601 41602 for ( var i = 0, l = this.points.length; i < l; i ++ ) { 41603 41604 var point = this.points[ i ]; 41605 data.points.push( point.toArray() ); 41606 41607 } 41608 41609 return data; 41610 41611 }; 41612 41613 SplineCurve.prototype.fromJSON = function ( json ) { 41614 41615 Curve.prototype.fromJSON.call( this, json ); 41616 41617 this.points = []; 41618 41619 for ( var i = 0, l = json.points.length; i < l; i ++ ) { 41620 41621 var point = json.points[ i ]; 41622 this.points.push( new Vector2().fromArray( point ) ); 41623 41624 } 41625 41626 return this; 41627 41628 }; 41629 41630 41631 41632 var Curves = /*#__PURE__*/Object.freeze({ 41633 ArcCurve: ArcCurve, 41634 CatmullRomCurve3: CatmullRomCurve3, 41635 CubicBezierCurve: CubicBezierCurve, 41636 CubicBezierCurve3: CubicBezierCurve3, 41637 EllipseCurve: EllipseCurve, 41638 LineCurve: LineCurve, 41639 LineCurve3: LineCurve3, 41640 QuadraticBezierCurve: QuadraticBezierCurve, 41641 QuadraticBezierCurve3: QuadraticBezierCurve3, 41642 SplineCurve: SplineCurve 41643 }); 41644 41645 /** 41646 * @author zz85 / http://www.lab4games.net/zz85/blog 41647 * 41648 **/ 41649 41650 /************************************************************** 41651 * Curved Path - a curve path is simply a array of connected 41652 * curves, but retains the api of a curve 41653 **************************************************************/ 41654 41655 function CurvePath() { 41656 41657 Curve.call( this ); 41658 41659 this.type = 'CurvePath'; 41660 41661 this.curves = []; 41662 this.autoClose = false; // Automatically closes the path 41663 41664 } 41665 41666 CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), { 41667 41668 constructor: CurvePath, 41669 41670 add: function ( curve ) { 41671 41672 this.curves.push( curve ); 41673 41674 }, 41675 41676 closePath: function () { 41677 41678 // Add a line curve if start and end of lines are not connected 41679 var startPoint = this.curves[ 0 ].getPoint( 0 ); 41680 var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); 41681 41682 if ( ! startPoint.equals( endPoint ) ) { 41683 41684 this.curves.push( new LineCurve( endPoint, startPoint ) ); 41685 41686 } 41687 41688 }, 41689 41690 // To get accurate point with reference to 41691 // entire path distance at time t, 41692 // following has to be done: 41693 41694 // 1. Length of each sub path have to be known 41695 // 2. Locate and identify type of curve 41696 // 3. Get t for the curve 41697 // 4. Return curve.getPointAt(t') 41698 41699 getPoint: function ( t ) { 41700 41701 var d = t * this.getLength(); 41702 var curveLengths = this.getCurveLengths(); 41703 var i = 0; 41704 41705 // To think about boundaries points. 41706 41707 while ( i < curveLengths.length ) { 41708 41709 if ( curveLengths[ i ] >= d ) { 41710 41711 var diff = curveLengths[ i ] - d; 41712 var curve = this.curves[ i ]; 41713 41714 var segmentLength = curve.getLength(); 41715 var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; 41716 41717 return curve.getPointAt( u ); 41718 41719 } 41720 41721 i ++; 41722 41723 } 41724 41725 return null; 41726 41727 // loop where sum != 0, sum > d , sum+1 <d 41728 41729 }, 41730 41731 // We cannot use the default THREE.Curve getPoint() with getLength() because in 41732 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath 41733 // getPoint() depends on getLength 41734 41735 getLength: function () { 41736 41737 var lens = this.getCurveLengths(); 41738 return lens[ lens.length - 1 ]; 41739 41740 }, 41741 41742 // cacheLengths must be recalculated. 41743 updateArcLengths: function () { 41744 41745 this.needsUpdate = true; 41746 this.cacheLengths = null; 41747 this.getCurveLengths(); 41748 41749 }, 41750 41751 // Compute lengths and cache them 41752 // We cannot overwrite getLengths() because UtoT mapping uses it. 41753 41754 getCurveLengths: function () { 41755 41756 // We use cache values if curves and cache array are same length 41757 41758 if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) { 41759 41760 return this.cacheLengths; 41761 41762 } 41763 41764 // Get length of sub-curve 41765 // Push sums into cached array 41766 41767 var lengths = [], sums = 0; 41768 41769 for ( var i = 0, l = this.curves.length; i < l; i ++ ) { 41770 41771 sums += this.curves[ i ].getLength(); 41772 lengths.push( sums ); 41773 41774 } 41775 41776 this.cacheLengths = lengths; 41777 41778 return lengths; 41779 41780 }, 41781 41782 getSpacedPoints: function ( divisions ) { 41783 41784 if ( divisions === undefined ) divisions = 40; 41785 41786 var points = []; 41787 41788 for ( var i = 0; i <= divisions; i ++ ) { 41789 41790 points.push( this.getPoint( i / divisions ) ); 41791 41792 } 41793 41794 if ( this.autoClose ) { 41795 41796 points.push( points[ 0 ] ); 41797 41798 } 41799 41800 return points; 41801 41802 }, 41803 41804 getPoints: function ( divisions ) { 41805 41806 divisions = divisions || 12; 41807 41808 var points = [], last; 41809 41810 for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) { 41811 41812 var curve = curves[ i ]; 41813 var resolution = ( curve && curve.isEllipseCurve ) ? divisions * 2 41814 : ( curve && curve.isLineCurve ) ? 1 41815 : ( curve && curve.isSplineCurve ) ? divisions * curve.points.length 41816 : divisions; 41817 41818 var pts = curve.getPoints( resolution ); 41819 41820 for ( var j = 0; j < pts.length; j ++ ) { 41821 41822 var point = pts[ j ]; 41823 41824 if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates 41825 41826 points.push( point ); 41827 last = point; 41828 41829 } 41830 41831 } 41832 41833 if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) { 41834 41835 points.push( points[ 0 ] ); 41836 41837 } 41838 41839 return points; 41840 41841 }, 41842 41843 copy: function ( source ) { 41844 41845 Curve.prototype.copy.call( this, source ); 41846 41847 this.curves = []; 41848 41849 for ( var i = 0, l = source.curves.length; i < l; i ++ ) { 41850 41851 var curve = source.curves[ i ]; 41852 41853 this.curves.push( curve.clone() ); 41854 41855 } 41856 41857 this.autoClose = source.autoClose; 41858 41859 return this; 41860 41861 }, 41862 41863 toJSON: function () { 41864 41865 var data = Curve.prototype.toJSON.call( this ); 41866 41867 data.autoClose = this.autoClose; 41868 data.curves = []; 41869 41870 for ( var i = 0, l = this.curves.length; i < l; i ++ ) { 41871 41872 var curve = this.curves[ i ]; 41873 data.curves.push( curve.toJSON() ); 41874 41875 } 41876 41877 return data; 41878 41879 }, 41880 41881 fromJSON: function ( json ) { 41882 41883 Curve.prototype.fromJSON.call( this, json ); 41884 41885 this.autoClose = json.autoClose; 41886 this.curves = []; 41887 41888 for ( var i = 0, l = json.curves.length; i < l; i ++ ) { 41889 41890 var curve = json.curves[ i ]; 41891 this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) ); 41892 41893 } 41894 41895 return this; 41896 41897 } 41898 41899 } ); 41900 41901 /** 41902 * @author zz85 / http://www.lab4games.net/zz85/blog 41903 * Creates free form 2d path using series of points, lines or curves. 41904 **/ 41905 41906 function Path( points ) { 41907 41908 CurvePath.call( this ); 41909 41910 this.type = 'Path'; 41911 41912 this.currentPoint = new Vector2(); 41913 41914 if ( points ) { 41915 41916 this.setFromPoints( points ); 41917 41918 } 41919 41920 } 41921 41922 Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { 41923 41924 constructor: Path, 41925 41926 setFromPoints: function ( points ) { 41927 41928 this.moveTo( points[ 0 ].x, points[ 0 ].y ); 41929 41930 for ( var i = 1, l = points.length; i < l; i ++ ) { 41931 41932 this.lineTo( points[ i ].x, points[ i ].y ); 41933 41934 } 41935 41936 }, 41937 41938 moveTo: function ( x, y ) { 41939 41940 this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? 41941 41942 }, 41943 41944 lineTo: function ( x, y ) { 41945 41946 var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) ); 41947 this.curves.push( curve ); 41948 41949 this.currentPoint.set( x, y ); 41950 41951 }, 41952 41953 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { 41954 41955 var curve = new QuadraticBezierCurve( 41956 this.currentPoint.clone(), 41957 new Vector2( aCPx, aCPy ), 41958 new Vector2( aX, aY ) 41959 ); 41960 41961 this.curves.push( curve ); 41962 41963 this.currentPoint.set( aX, aY ); 41964 41965 }, 41966 41967 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { 41968 41969 var curve = new CubicBezierCurve( 41970 this.currentPoint.clone(), 41971 new Vector2( aCP1x, aCP1y ), 41972 new Vector2( aCP2x, aCP2y ), 41973 new Vector2( aX, aY ) 41974 ); 41975 41976 this.curves.push( curve ); 41977 41978 this.currentPoint.set( aX, aY ); 41979 41980 }, 41981 41982 splineThru: function ( pts /*Array of Vector*/ ) { 41983 41984 var npts = [ this.currentPoint.clone() ].concat( pts ); 41985 41986 var curve = new SplineCurve( npts ); 41987 this.curves.push( curve ); 41988 41989 this.currentPoint.copy( pts[ pts.length - 1 ] ); 41990 41991 }, 41992 41993 arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 41994 41995 var x0 = this.currentPoint.x; 41996 var y0 = this.currentPoint.y; 41997 41998 this.absarc( aX + x0, aY + y0, aRadius, 41999 aStartAngle, aEndAngle, aClockwise ); 42000 42001 }, 42002 42003 absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { 42004 42005 this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); 42006 42007 }, 42008 42009 ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 42010 42011 var x0 = this.currentPoint.x; 42012 var y0 = this.currentPoint.y; 42013 42014 this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); 42015 42016 }, 42017 42018 absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { 42019 42020 var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); 42021 42022 if ( this.curves.length > 0 ) { 42023 42024 // if a previous curve is present, attempt to join 42025 var firstPoint = curve.getPoint( 0 ); 42026 42027 if ( ! firstPoint.equals( this.currentPoint ) ) { 42028 42029 this.lineTo( firstPoint.x, firstPoint.y ); 42030 42031 } 42032 42033 } 42034 42035 this.curves.push( curve ); 42036 42037 var lastPoint = curve.getPoint( 1 ); 42038 this.currentPoint.copy( lastPoint ); 42039 42040 }, 42041 42042 copy: function ( source ) { 42043 42044 CurvePath.prototype.copy.call( this, source ); 42045 42046 this.currentPoint.copy( source.currentPoint ); 42047 42048 return this; 42049 42050 }, 42051 42052 toJSON: function () { 42053 42054 var data = CurvePath.prototype.toJSON.call( this ); 42055 42056 data.currentPoint = this.currentPoint.toArray(); 42057 42058 return data; 42059 42060 }, 42061 42062 fromJSON: function ( json ) { 42063 42064 CurvePath.prototype.fromJSON.call( this, json ); 42065 42066 this.currentPoint.fromArray( json.currentPoint ); 42067 42068 return this; 42069 42070 } 42071 42072 } ); 42073 42074 /** 42075 * @author zz85 / http://www.lab4games.net/zz85/blog 42076 * Defines a 2d shape plane using paths. 42077 **/ 42078 42079 // STEP 1 Create a path. 42080 // STEP 2 Turn path into shape. 42081 // STEP 3 ExtrudeGeometry takes in Shape/Shapes 42082 // STEP 3a - Extract points from each shape, turn to vertices 42083 // STEP 3b - Triangulate each shape, add faces. 42084 42085 function Shape( points ) { 42086 42087 Path.call( this, points ); 42088 42089 this.uuid = _Math.generateUUID(); 42090 42091 this.type = 'Shape'; 42092 42093 this.holes = []; 42094 42095 } 42096 42097 Shape.prototype = Object.assign( Object.create( Path.prototype ), { 42098 42099 constructor: Shape, 42100 42101 getPointsHoles: function ( divisions ) { 42102 42103 var holesPts = []; 42104 42105 for ( var i = 0, l = this.holes.length; i < l; i ++ ) { 42106 42107 holesPts[ i ] = this.holes[ i ].getPoints( divisions ); 42108 42109 } 42110 42111 return holesPts; 42112 42113 }, 42114 42115 // get points of shape and holes (keypoints based on segments parameter) 42116 42117 extractPoints: function ( divisions ) { 42118 42119 return { 42120 42121 shape: this.getPoints( divisions ), 42122 holes: this.getPointsHoles( divisions ) 42123 42124 }; 42125 42126 }, 42127 42128 copy: function ( source ) { 42129 42130 Path.prototype.copy.call( this, source ); 42131 42132 this.holes = []; 42133 42134 for ( var i = 0, l = source.holes.length; i < l; i ++ ) { 42135 42136 var hole = source.holes[ i ]; 42137 42138 this.holes.push( hole.clone() ); 42139 42140 } 42141 42142 return this; 42143 42144 }, 42145 42146 toJSON: function () { 42147 42148 var data = Path.prototype.toJSON.call( this ); 42149 42150 data.uuid = this.uuid; 42151 data.holes = []; 42152 42153 for ( var i = 0, l = this.holes.length; i < l; i ++ ) { 42154 42155 var hole = this.holes[ i ]; 42156 data.holes.push( hole.toJSON() ); 42157 42158 } 42159 42160 return data; 42161 42162 }, 42163 42164 fromJSON: function ( json ) { 42165 42166 Path.prototype.fromJSON.call( this, json ); 42167 42168 this.uuid = json.uuid; 42169 this.holes = []; 42170 42171 for ( var i = 0, l = json.holes.length; i < l; i ++ ) { 42172 42173 var hole = json.holes[ i ]; 42174 this.holes.push( new Path().fromJSON( hole ) ); 42175 42176 } 42177 42178 return this; 42179 42180 } 42181 42182 } ); 42183 42184 /** 42185 * @author mrdoob / http://mrdoob.com/ 42186 * @author alteredq / http://alteredqualia.com/ 42187 */ 42188 42189 function Light( color, intensity ) { 42190 42191 Object3D.call( this ); 42192 42193 this.type = 'Light'; 42194 42195 this.color = new Color( color ); 42196 this.intensity = intensity !== undefined ? intensity : 1; 42197 42198 this.receiveShadow = undefined; 42199 42200 } 42201 42202 Light.prototype = Object.assign( Object.create( Object3D.prototype ), { 42203 42204 constructor: Light, 42205 42206 isLight: true, 42207 42208 copy: function ( source ) { 42209 42210 Object3D.prototype.copy.call( this, source ); 42211 42212 this.color.copy( source.color ); 42213 this.intensity = source.intensity; 42214 42215 return this; 42216 42217 }, 42218 42219 toJSON: function ( meta ) { 42220 42221 var data = Object3D.prototype.toJSON.call( this, meta ); 42222 42223 data.object.color = this.color.getHex(); 42224 data.object.intensity = this.intensity; 42225 42226 if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); 42227 42228 if ( this.distance !== undefined ) data.object.distance = this.distance; 42229 if ( this.angle !== undefined ) data.object.angle = this.angle; 42230 if ( this.decay !== undefined ) data.object.decay = this.decay; 42231 if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; 42232 42233 if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); 42234 42235 return data; 42236 42237 } 42238 42239 } ); 42240 42241 /** 42242 * @author alteredq / http://alteredqualia.com/ 42243 */ 42244 42245 function HemisphereLight( skyColor, groundColor, intensity ) { 42246 42247 Light.call( this, skyColor, intensity ); 42248 42249 this.type = 'HemisphereLight'; 42250 42251 this.castShadow = undefined; 42252 42253 this.position.copy( Object3D.DefaultUp ); 42254 this.updateMatrix(); 42255 42256 this.groundColor = new Color( groundColor ); 42257 42258 } 42259 42260 HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), { 42261 42262 constructor: HemisphereLight, 42263 42264 isHemisphereLight: true, 42265 42266 copy: function ( source ) { 42267 42268 Light.prototype.copy.call( this, source ); 42269 42270 this.groundColor.copy( source.groundColor ); 42271 42272 return this; 42273 42274 } 42275 42276 } ); 42277 42278 /** 42279 * @author mrdoob / http://mrdoob.com/ 42280 */ 42281 42282 function LightShadow( camera ) { 42283 42284 this.camera = camera; 42285 42286 this.bias = 0; 42287 this.radius = 1; 42288 42289 this.mapSize = new Vector2( 512, 512 ); 42290 42291 this.map = null; 42292 this.matrix = new Matrix4(); 42293 42294 } 42295 42296 Object.assign( LightShadow.prototype, { 42297 42298 copy: function ( source ) { 42299 42300 this.camera = source.camera.clone(); 42301 42302 this.bias = source.bias; 42303 this.radius = source.radius; 42304 42305 this.mapSize.copy( source.mapSize ); 42306 42307 return this; 42308 42309 }, 42310 42311 clone: function () { 42312 42313 return new this.constructor().copy( this ); 42314 42315 }, 42316 42317 toJSON: function () { 42318 42319 var object = {}; 42320 42321 if ( this.bias !== 0 ) object.bias = this.bias; 42322 if ( this.radius !== 1 ) object.radius = this.radius; 42323 if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); 42324 42325 object.camera = this.camera.toJSON( false ).object; 42326 delete object.camera.matrix; 42327 42328 return object; 42329 42330 } 42331 42332 } ); 42333 42334 /** 42335 * @author mrdoob / http://mrdoob.com/ 42336 */ 42337 42338 function SpotLightShadow() { 42339 42340 LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) ); 42341 42342 } 42343 42344 SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { 42345 42346 constructor: SpotLightShadow, 42347 42348 isSpotLightShadow: true, 42349 42350 update: function ( light ) { 42351 42352 var camera = this.camera; 42353 42354 var fov = _Math.RAD2DEG * 2 * light.angle; 42355 var aspect = this.mapSize.width / this.mapSize.height; 42356 var far = light.distance || camera.far; 42357 42358 if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) { 42359 42360 camera.fov = fov; 42361 camera.aspect = aspect; 42362 camera.far = far; 42363 camera.updateProjectionMatrix(); 42364 42365 } 42366 42367 } 42368 42369 } ); 42370 42371 /** 42372 * @author alteredq / http://alteredqualia.com/ 42373 */ 42374 42375 function SpotLight( color, intensity, distance, angle, penumbra, decay ) { 42376 42377 Light.call( this, color, intensity ); 42378 42379 this.type = 'SpotLight'; 42380 42381 this.position.copy( Object3D.DefaultUp ); 42382 this.updateMatrix(); 42383 42384 this.target = new Object3D(); 42385 42386 Object.defineProperty( this, 'power', { 42387 get: function () { 42388 42389 // intensity = power per solid angle. 42390 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 42391 return this.intensity * Math.PI; 42392 42393 }, 42394 set: function ( power ) { 42395 42396 // intensity = power per solid angle. 42397 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 42398 this.intensity = power / Math.PI; 42399 42400 } 42401 } ); 42402 42403 this.distance = ( distance !== undefined ) ? distance : 0; 42404 this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; 42405 this.penumbra = ( penumbra !== undefined ) ? penumbra : 0; 42406 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. 42407 42408 this.shadow = new SpotLightShadow(); 42409 42410 } 42411 42412 SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { 42413 42414 constructor: SpotLight, 42415 42416 isSpotLight: true, 42417 42418 copy: function ( source ) { 42419 42420 Light.prototype.copy.call( this, source ); 42421 42422 this.distance = source.distance; 42423 this.angle = source.angle; 42424 this.penumbra = source.penumbra; 42425 this.decay = source.decay; 42426 42427 this.target = source.target.clone(); 42428 42429 this.shadow = source.shadow.clone(); 42430 42431 return this; 42432 42433 } 42434 42435 } ); 42436 42437 /** 42438 * @author mrdoob / http://mrdoob.com/ 42439 */ 42440 42441 42442 function PointLight( color, intensity, distance, decay ) { 42443 42444 Light.call( this, color, intensity ); 42445 42446 this.type = 'PointLight'; 42447 42448 Object.defineProperty( this, 'power', { 42449 get: function () { 42450 42451 // intensity = power per solid angle. 42452 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 42453 return this.intensity * 4 * Math.PI; 42454 42455 }, 42456 set: function ( power ) { 42457 42458 // intensity = power per solid angle. 42459 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf 42460 this.intensity = power / ( 4 * Math.PI ); 42461 42462 } 42463 } ); 42464 42465 this.distance = ( distance !== undefined ) ? distance : 0; 42466 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. 42467 42468 this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); 42469 42470 } 42471 42472 PointLight.prototype = Object.assign( Object.create( Light.prototype ), { 42473 42474 constructor: PointLight, 42475 42476 isPointLight: true, 42477 42478 copy: function ( source ) { 42479 42480 Light.prototype.copy.call( this, source ); 42481 42482 this.distance = source.distance; 42483 this.decay = source.decay; 42484 42485 this.shadow = source.shadow.clone(); 42486 42487 return this; 42488 42489 } 42490 42491 } ); 42492 42493 /** 42494 * @author mrdoob / http://mrdoob.com/ 42495 */ 42496 42497 function DirectionalLightShadow( ) { 42498 42499 LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); 42500 42501 } 42502 42503 DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { 42504 42505 constructor: DirectionalLightShadow 42506 42507 } ); 42508 42509 /** 42510 * @author mrdoob / http://mrdoob.com/ 42511 * @author alteredq / http://alteredqualia.com/ 42512 */ 42513 42514 function DirectionalLight( color, intensity ) { 42515 42516 Light.call( this, color, intensity ); 42517 42518 this.type = 'DirectionalLight'; 42519 42520 this.position.copy( Object3D.DefaultUp ); 42521 this.updateMatrix(); 42522 42523 this.target = new Object3D(); 42524 42525 this.shadow = new DirectionalLightShadow(); 42526 42527 } 42528 42529 DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { 42530 42531 constructor: DirectionalLight, 42532 42533 isDirectionalLight: true, 42534 42535 copy: function ( source ) { 42536 42537 Light.prototype.copy.call( this, source ); 42538 42539 this.target = source.target.clone(); 42540 42541 this.shadow = source.shadow.clone(); 42542 42543 return this; 42544 42545 } 42546 42547 } ); 42548 42549 /** 42550 * @author mrdoob / http://mrdoob.com/ 42551 */ 42552 42553 function AmbientLight( color, intensity ) { 42554 42555 Light.call( this, color, intensity ); 42556 42557 this.type = 'AmbientLight'; 42558 42559 this.castShadow = undefined; 42560 42561 } 42562 42563 AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), { 42564 42565 constructor: AmbientLight, 42566 42567 isAmbientLight: true 42568 42569 } ); 42570 42571 /** 42572 * @author abelnation / http://github.com/abelnation 42573 */ 42574 42575 function RectAreaLight( color, intensity, width, height ) { 42576 42577 Light.call( this, color, intensity ); 42578 42579 this.type = 'RectAreaLight'; 42580 42581 this.width = ( width !== undefined ) ? width : 10; 42582 this.height = ( height !== undefined ) ? height : 10; 42583 42584 } 42585 42586 RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), { 42587 42588 constructor: RectAreaLight, 42589 42590 isRectAreaLight: true, 42591 42592 copy: function ( source ) { 42593 42594 Light.prototype.copy.call( this, source ); 42595 42596 this.width = source.width; 42597 this.height = source.height; 42598 42599 return this; 42600 42601 }, 42602 42603 toJSON: function ( meta ) { 42604 42605 var data = Light.prototype.toJSON.call( this, meta ); 42606 42607 data.object.width = this.width; 42608 data.object.height = this.height; 42609 42610 return data; 42611 42612 } 42613 42614 } ); 42615 42616 /** 42617 * 42618 * A Track that interpolates Strings 42619 * 42620 * 42621 * @author Ben Houston / http://clara.io/ 42622 * @author David Sarno / http://lighthaus.us/ 42623 * @author tschw 42624 */ 42625 42626 function StringKeyframeTrack( name, times, values, interpolation ) { 42627 42628 KeyframeTrack.call( this, name, times, values, interpolation ); 42629 42630 } 42631 42632 StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 42633 42634 constructor: StringKeyframeTrack, 42635 42636 ValueTypeName: 'string', 42637 ValueBufferType: Array, 42638 42639 DefaultInterpolation: InterpolateDiscrete, 42640 42641 InterpolantFactoryMethodLinear: undefined, 42642 42643 InterpolantFactoryMethodSmooth: undefined 42644 42645 } ); 42646 42647 /** 42648 * 42649 * A Track of Boolean keyframe values. 42650 * 42651 * 42652 * @author Ben Houston / http://clara.io/ 42653 * @author David Sarno / http://lighthaus.us/ 42654 * @author tschw 42655 */ 42656 42657 function BooleanKeyframeTrack( name, times, values ) { 42658 42659 KeyframeTrack.call( this, name, times, values ); 42660 42661 } 42662 42663 BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 42664 42665 constructor: BooleanKeyframeTrack, 42666 42667 ValueTypeName: 'bool', 42668 ValueBufferType: Array, 42669 42670 DefaultInterpolation: InterpolateDiscrete, 42671 42672 InterpolantFactoryMethodLinear: undefined, 42673 InterpolantFactoryMethodSmooth: undefined 42674 42675 // Note: Actually this track could have a optimized / compressed 42676 // representation of a single value and a custom interpolant that 42677 // computes "firstValue ^ isOdd( index )". 42678 42679 } ); 42680 42681 /** 42682 * Abstract base class of interpolants over parametric samples. 42683 * 42684 * The parameter domain is one dimensional, typically the time or a path 42685 * along a curve defined by the data. 42686 * 42687 * The sample values can have any dimensionality and derived classes may 42688 * apply special interpretations to the data. 42689 * 42690 * This class provides the interval seek in a Template Method, deferring 42691 * the actual interpolation to derived classes. 42692 * 42693 * Time complexity is O(1) for linear access crossing at most two points 42694 * and O(log N) for random access, where N is the number of positions. 42695 * 42696 * References: 42697 * 42698 * http://www.oodesign.com/template-method-pattern.html 42699 * 42700 * @author tschw 42701 */ 42702 42703 function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 42704 42705 this.parameterPositions = parameterPositions; 42706 this._cachedIndex = 0; 42707 42708 this.resultBuffer = resultBuffer !== undefined ? 42709 resultBuffer : new sampleValues.constructor( sampleSize ); 42710 this.sampleValues = sampleValues; 42711 this.valueSize = sampleSize; 42712 42713 } 42714 42715 Object.assign( Interpolant.prototype, { 42716 42717 evaluate: function ( t ) { 42718 42719 var pp = this.parameterPositions, 42720 i1 = this._cachedIndex, 42721 42722 t1 = pp[ i1 ], 42723 t0 = pp[ i1 - 1 ]; 42724 42725 validate_interval: { 42726 42727 seek: { 42728 42729 var right; 42730 42731 linear_scan: { 42732 42733 //- See http://jsperf.com/comparison-to-undefined/3 42734 //- slower code: 42735 //- 42736 //- if ( t >= t1 || t1 === undefined ) { 42737 forward_scan: if ( ! ( t < t1 ) ) { 42738 42739 for ( var giveUpAt = i1 + 2; ; ) { 42740 42741 if ( t1 === undefined ) { 42742 42743 if ( t < t0 ) break forward_scan; 42744 42745 // after end 42746 42747 i1 = pp.length; 42748 this._cachedIndex = i1; 42749 return this.afterEnd_( i1 - 1, t, t0 ); 42750 42751 } 42752 42753 if ( i1 === giveUpAt ) break; // this loop 42754 42755 t0 = t1; 42756 t1 = pp[ ++ i1 ]; 42757 42758 if ( t < t1 ) { 42759 42760 // we have arrived at the sought interval 42761 break seek; 42762 42763 } 42764 42765 } 42766 42767 // prepare binary search on the right side of the index 42768 right = pp.length; 42769 break linear_scan; 42770 42771 } 42772 42773 //- slower code: 42774 //- if ( t < t0 || t0 === undefined ) { 42775 if ( ! ( t >= t0 ) ) { 42776 42777 // looping? 42778 42779 var t1global = pp[ 1 ]; 42780 42781 if ( t < t1global ) { 42782 42783 i1 = 2; // + 1, using the scan for the details 42784 t0 = t1global; 42785 42786 } 42787 42788 // linear reverse scan 42789 42790 for ( var giveUpAt = i1 - 2; ; ) { 42791 42792 if ( t0 === undefined ) { 42793 42794 // before start 42795 42796 this._cachedIndex = 0; 42797 return this.beforeStart_( 0, t, t1 ); 42798 42799 } 42800 42801 if ( i1 === giveUpAt ) break; // this loop 42802 42803 t1 = t0; 42804 t0 = pp[ -- i1 - 1 ]; 42805 42806 if ( t >= t0 ) { 42807 42808 // we have arrived at the sought interval 42809 break seek; 42810 42811 } 42812 42813 } 42814 42815 // prepare binary search on the left side of the index 42816 right = i1; 42817 i1 = 0; 42818 break linear_scan; 42819 42820 } 42821 42822 // the interval is valid 42823 42824 break validate_interval; 42825 42826 } // linear scan 42827 42828 // binary search 42829 42830 while ( i1 < right ) { 42831 42832 var mid = ( i1 + right ) >>> 1; 42833 42834 if ( t < pp[ mid ] ) { 42835 42836 right = mid; 42837 42838 } else { 42839 42840 i1 = mid + 1; 42841 42842 } 42843 42844 } 42845 42846 t1 = pp[ i1 ]; 42847 t0 = pp[ i1 - 1 ]; 42848 42849 // check boundary cases, again 42850 42851 if ( t0 === undefined ) { 42852 42853 this._cachedIndex = 0; 42854 return this.beforeStart_( 0, t, t1 ); 42855 42856 } 42857 42858 if ( t1 === undefined ) { 42859 42860 i1 = pp.length; 42861 this._cachedIndex = i1; 42862 return this.afterEnd_( i1 - 1, t0, t ); 42863 42864 } 42865 42866 } // seek 42867 42868 this._cachedIndex = i1; 42869 42870 this.intervalChanged_( i1, t0, t1 ); 42871 42872 } // validate_interval 42873 42874 return this.interpolate_( i1, t0, t, t1 ); 42875 42876 }, 42877 42878 settings: null, // optional, subclass-specific settings structure 42879 // Note: The indirection allows central control of many interpolants. 42880 42881 // --- Protected interface 42882 42883 DefaultSettings_: {}, 42884 42885 getSettings_: function () { 42886 42887 return this.settings || this.DefaultSettings_; 42888 42889 }, 42890 42891 copySampleValue_: function ( index ) { 42892 42893 // copies a sample value to the result buffer 42894 42895 var result = this.resultBuffer, 42896 values = this.sampleValues, 42897 stride = this.valueSize, 42898 offset = index * stride; 42899 42900 for ( var i = 0; i !== stride; ++ i ) { 42901 42902 result[ i ] = values[ offset + i ]; 42903 42904 } 42905 42906 return result; 42907 42908 }, 42909 42910 // Template methods for derived classes: 42911 42912 interpolate_: function ( /* i1, t0, t, t1 */ ) { 42913 42914 throw new Error( 'call to abstract method' ); 42915 // implementations shall return this.resultBuffer 42916 42917 }, 42918 42919 intervalChanged_: function ( /* i1, t0, t1 */ ) { 42920 42921 // empty 42922 42923 } 42924 42925 } ); 42926 42927 //!\ DECLARE ALIAS AFTER assign prototype ! 42928 Object.assign( Interpolant.prototype, { 42929 42930 //( 0, t, t0 ), returns this.resultBuffer 42931 beforeStart_: Interpolant.prototype.copySampleValue_, 42932 42933 //( N-1, tN-1, t ), returns this.resultBuffer 42934 afterEnd_: Interpolant.prototype.copySampleValue_, 42935 42936 } ); 42937 42938 /** 42939 * Spherical linear unit quaternion interpolant. 42940 * 42941 * @author tschw 42942 */ 42943 42944 function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 42945 42946 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 42947 42948 } 42949 42950 QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 42951 42952 constructor: QuaternionLinearInterpolant, 42953 42954 interpolate_: function ( i1, t0, t, t1 ) { 42955 42956 var result = this.resultBuffer, 42957 values = this.sampleValues, 42958 stride = this.valueSize, 42959 42960 offset = i1 * stride, 42961 42962 alpha = ( t - t0 ) / ( t1 - t0 ); 42963 42964 for ( var end = offset + stride; offset !== end; offset += 4 ) { 42965 42966 Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha ); 42967 42968 } 42969 42970 return result; 42971 42972 } 42973 42974 } ); 42975 42976 /** 42977 * 42978 * A Track of quaternion keyframe values. 42979 * 42980 * @author Ben Houston / http://clara.io/ 42981 * @author David Sarno / http://lighthaus.us/ 42982 * @author tschw 42983 */ 42984 42985 function QuaternionKeyframeTrack( name, times, values, interpolation ) { 42986 42987 KeyframeTrack.call( this, name, times, values, interpolation ); 42988 42989 } 42990 42991 QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 42992 42993 constructor: QuaternionKeyframeTrack, 42994 42995 ValueTypeName: 'quaternion', 42996 42997 // ValueBufferType is inherited 42998 42999 DefaultInterpolation: InterpolateLinear, 43000 43001 InterpolantFactoryMethodLinear: function ( result ) { 43002 43003 return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result ); 43004 43005 }, 43006 43007 InterpolantFactoryMethodSmooth: undefined // not yet implemented 43008 43009 } ); 43010 43011 /** 43012 * 43013 * A Track of keyframe values that represent color. 43014 * 43015 * 43016 * @author Ben Houston / http://clara.io/ 43017 * @author David Sarno / http://lighthaus.us/ 43018 * @author tschw 43019 */ 43020 43021 function ColorKeyframeTrack( name, times, values, interpolation ) { 43022 43023 KeyframeTrack.call( this, name, times, values, interpolation ); 43024 43025 } 43026 43027 ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 43028 43029 constructor: ColorKeyframeTrack, 43030 43031 ValueTypeName: 'color' 43032 43033 // ValueBufferType is inherited 43034 43035 // DefaultInterpolation is inherited 43036 43037 // Note: Very basic implementation and nothing special yet. 43038 // However, this is the place for color space parameterization. 43039 43040 } ); 43041 43042 /** 43043 * 43044 * A Track of numeric keyframe values. 43045 * 43046 * @author Ben Houston / http://clara.io/ 43047 * @author David Sarno / http://lighthaus.us/ 43048 * @author tschw 43049 */ 43050 43051 function NumberKeyframeTrack( name, times, values, interpolation ) { 43052 43053 KeyframeTrack.call( this, name, times, values, interpolation ); 43054 43055 } 43056 43057 NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 43058 43059 constructor: NumberKeyframeTrack, 43060 43061 ValueTypeName: 'number' 43062 43063 // ValueBufferType is inherited 43064 43065 // DefaultInterpolation is inherited 43066 43067 } ); 43068 43069 /** 43070 * Fast and simple cubic spline interpolant. 43071 * 43072 * It was derived from a Hermitian construction setting the first derivative 43073 * at each sample position to the linear slope between neighboring positions 43074 * over their parameter interval. 43075 * 43076 * @author tschw 43077 */ 43078 43079 function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 43080 43081 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 43082 43083 this._weightPrev = - 0; 43084 this._offsetPrev = - 0; 43085 this._weightNext = - 0; 43086 this._offsetNext = - 0; 43087 43088 } 43089 43090 CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 43091 43092 constructor: CubicInterpolant, 43093 43094 DefaultSettings_: { 43095 43096 endingStart: ZeroCurvatureEnding, 43097 endingEnd: ZeroCurvatureEnding 43098 43099 }, 43100 43101 intervalChanged_: function ( i1, t0, t1 ) { 43102 43103 var pp = this.parameterPositions, 43104 iPrev = i1 - 2, 43105 iNext = i1 + 1, 43106 43107 tPrev = pp[ iPrev ], 43108 tNext = pp[ iNext ]; 43109 43110 if ( tPrev === undefined ) { 43111 43112 switch ( this.getSettings_().endingStart ) { 43113 43114 case ZeroSlopeEnding: 43115 43116 // f'(t0) = 0 43117 iPrev = i1; 43118 tPrev = 2 * t0 - t1; 43119 43120 break; 43121 43122 case WrapAroundEnding: 43123 43124 // use the other end of the curve 43125 iPrev = pp.length - 2; 43126 tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ]; 43127 43128 break; 43129 43130 default: // ZeroCurvatureEnding 43131 43132 // f''(t0) = 0 a.k.a. Natural Spline 43133 iPrev = i1; 43134 tPrev = t1; 43135 43136 } 43137 43138 } 43139 43140 if ( tNext === undefined ) { 43141 43142 switch ( this.getSettings_().endingEnd ) { 43143 43144 case ZeroSlopeEnding: 43145 43146 // f'(tN) = 0 43147 iNext = i1; 43148 tNext = 2 * t1 - t0; 43149 43150 break; 43151 43152 case WrapAroundEnding: 43153 43154 // use the other end of the curve 43155 iNext = 1; 43156 tNext = t1 + pp[ 1 ] - pp[ 0 ]; 43157 43158 break; 43159 43160 default: // ZeroCurvatureEnding 43161 43162 // f''(tN) = 0, a.k.a. Natural Spline 43163 iNext = i1 - 1; 43164 tNext = t0; 43165 43166 } 43167 43168 } 43169 43170 var halfDt = ( t1 - t0 ) * 0.5, 43171 stride = this.valueSize; 43172 43173 this._weightPrev = halfDt / ( t0 - tPrev ); 43174 this._weightNext = halfDt / ( tNext - t1 ); 43175 this._offsetPrev = iPrev * stride; 43176 this._offsetNext = iNext * stride; 43177 43178 }, 43179 43180 interpolate_: function ( i1, t0, t, t1 ) { 43181 43182 var result = this.resultBuffer, 43183 values = this.sampleValues, 43184 stride = this.valueSize, 43185 43186 o1 = i1 * stride, o0 = o1 - stride, 43187 oP = this._offsetPrev, oN = this._offsetNext, 43188 wP = this._weightPrev, wN = this._weightNext, 43189 43190 p = ( t - t0 ) / ( t1 - t0 ), 43191 pp = p * p, 43192 ppp = pp * p; 43193 43194 // evaluate polynomials 43195 43196 var sP = - wP * ppp + 2 * wP * pp - wP * p; 43197 var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1; 43198 var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p; 43199 var sN = wN * ppp - wN * pp; 43200 43201 // combine data linearly 43202 43203 for ( var i = 0; i !== stride; ++ i ) { 43204 43205 result[ i ] = 43206 sP * values[ oP + i ] + 43207 s0 * values[ o0 + i ] + 43208 s1 * values[ o1 + i ] + 43209 sN * values[ oN + i ]; 43210 43211 } 43212 43213 return result; 43214 43215 } 43216 43217 } ); 43218 43219 /** 43220 * @author tschw 43221 */ 43222 43223 function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 43224 43225 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 43226 43227 } 43228 43229 LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 43230 43231 constructor: LinearInterpolant, 43232 43233 interpolate_: function ( i1, t0, t, t1 ) { 43234 43235 var result = this.resultBuffer, 43236 values = this.sampleValues, 43237 stride = this.valueSize, 43238 43239 offset1 = i1 * stride, 43240 offset0 = offset1 - stride, 43241 43242 weight1 = ( t - t0 ) / ( t1 - t0 ), 43243 weight0 = 1 - weight1; 43244 43245 for ( var i = 0; i !== stride; ++ i ) { 43246 43247 result[ i ] = 43248 values[ offset0 + i ] * weight0 + 43249 values[ offset1 + i ] * weight1; 43250 43251 } 43252 43253 return result; 43254 43255 } 43256 43257 } ); 43258 43259 /** 43260 * 43261 * Interpolant that evaluates to the sample value at the position preceeding 43262 * the parameter. 43263 * 43264 * @author tschw 43265 */ 43266 43267 function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { 43268 43269 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); 43270 43271 } 43272 43273 DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { 43274 43275 constructor: DiscreteInterpolant, 43276 43277 interpolate_: function ( i1 /*, t0, t, t1 */ ) { 43278 43279 return this.copySampleValue_( i1 - 1 ); 43280 43281 } 43282 43283 } ); 43284 43285 /** 43286 * @author tschw 43287 * @author Ben Houston / http://clara.io/ 43288 * @author David Sarno / http://lighthaus.us/ 43289 */ 43290 43291 var AnimationUtils = { 43292 43293 // same as Array.prototype.slice, but also works on typed arrays 43294 arraySlice: function ( array, from, to ) { 43295 43296 if ( AnimationUtils.isTypedArray( array ) ) { 43297 43298 // in ios9 array.subarray(from, undefined) will return empty array 43299 // but array.subarray(from) or array.subarray(from, len) is correct 43300 return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) ); 43301 43302 } 43303 43304 return array.slice( from, to ); 43305 43306 }, 43307 43308 // converts an array to a specific type 43309 convertArray: function ( array, type, forceClone ) { 43310 43311 if ( ! array || // let 'undefined' and 'null' pass 43312 ! forceClone && array.constructor === type ) return array; 43313 43314 if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { 43315 43316 return new type( array ); // create typed array 43317 43318 } 43319 43320 return Array.prototype.slice.call( array ); // create Array 43321 43322 }, 43323 43324 isTypedArray: function ( object ) { 43325 43326 return ArrayBuffer.isView( object ) && 43327 ! ( object instanceof DataView ); 43328 43329 }, 43330 43331 // returns an array by which times and values can be sorted 43332 getKeyframeOrder: function ( times ) { 43333 43334 function compareTime( i, j ) { 43335 43336 return times[ i ] - times[ j ]; 43337 43338 } 43339 43340 var n = times.length; 43341 var result = new Array( n ); 43342 for ( var i = 0; i !== n; ++ i ) result[ i ] = i; 43343 43344 result.sort( compareTime ); 43345 43346 return result; 43347 43348 }, 43349 43350 // uses the array previously returned by 'getKeyframeOrder' to sort data 43351 sortedArray: function ( values, stride, order ) { 43352 43353 var nValues = values.length; 43354 var result = new values.constructor( nValues ); 43355 43356 for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { 43357 43358 var srcOffset = order[ i ] * stride; 43359 43360 for ( var j = 0; j !== stride; ++ j ) { 43361 43362 result[ dstOffset ++ ] = values[ srcOffset + j ]; 43363 43364 } 43365 43366 } 43367 43368 return result; 43369 43370 }, 43371 43372 // function for parsing AOS keyframe formats 43373 flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) { 43374 43375 var i = 1, key = jsonKeys[ 0 ]; 43376 43377 while ( key !== undefined && key[ valuePropertyName ] === undefined ) { 43378 43379 key = jsonKeys[ i ++ ]; 43380 43381 } 43382 43383 if ( key === undefined ) return; // no data 43384 43385 var value = key[ valuePropertyName ]; 43386 if ( value === undefined ) return; // no data 43387 43388 if ( Array.isArray( value ) ) { 43389 43390 do { 43391 43392 value = key[ valuePropertyName ]; 43393 43394 if ( value !== undefined ) { 43395 43396 times.push( key.time ); 43397 values.push.apply( values, value ); // push all elements 43398 43399 } 43400 43401 key = jsonKeys[ i ++ ]; 43402 43403 } while ( key !== undefined ); 43404 43405 } else if ( value.toArray !== undefined ) { 43406 43407 // ...assume THREE.Math-ish 43408 43409 do { 43410 43411 value = key[ valuePropertyName ]; 43412 43413 if ( value !== undefined ) { 43414 43415 times.push( key.time ); 43416 value.toArray( values, values.length ); 43417 43418 } 43419 43420 key = jsonKeys[ i ++ ]; 43421 43422 } while ( key !== undefined ); 43423 43424 } else { 43425 43426 // otherwise push as-is 43427 43428 do { 43429 43430 value = key[ valuePropertyName ]; 43431 43432 if ( value !== undefined ) { 43433 43434 times.push( key.time ); 43435 values.push( value ); 43436 43437 } 43438 43439 key = jsonKeys[ i ++ ]; 43440 43441 } while ( key !== undefined ); 43442 43443 } 43444 43445 } 43446 43447 }; 43448 43449 /** 43450 * 43451 * A timed sequence of keyframes for a specific property. 43452 * 43453 * 43454 * @author Ben Houston / http://clara.io/ 43455 * @author David Sarno / http://lighthaus.us/ 43456 * @author tschw 43457 */ 43458 43459 function KeyframeTrack( name, times, values, interpolation ) { 43460 43461 if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); 43462 if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); 43463 43464 this.name = name; 43465 43466 this.times = AnimationUtils.convertArray( times, this.TimeBufferType ); 43467 this.values = AnimationUtils.convertArray( values, this.ValueBufferType ); 43468 43469 this.setInterpolation( interpolation || this.DefaultInterpolation ); 43470 43471 this.validate(); 43472 this.optimize(); 43473 43474 } 43475 43476 // Static methods: 43477 43478 Object.assign( KeyframeTrack, { 43479 43480 // Serialization (in static context, because of constructor invocation 43481 // and automatic invocation of .toJSON): 43482 43483 parse: function ( json ) { 43484 43485 if ( json.type === undefined ) { 43486 43487 throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' ); 43488 43489 } 43490 43491 var trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type ); 43492 43493 if ( json.times === undefined ) { 43494 43495 var times = [], values = []; 43496 43497 AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); 43498 43499 json.times = times; 43500 json.values = values; 43501 43502 } 43503 43504 // derived classes can define a static parse method 43505 if ( trackType.parse !== undefined ) { 43506 43507 return trackType.parse( json ); 43508 43509 } else { 43510 43511 // by default, we assume a constructor compatible with the base 43512 return new trackType( json.name, json.times, json.values, json.interpolation ); 43513 43514 } 43515 43516 }, 43517 43518 toJSON: function ( track ) { 43519 43520 var trackType = track.constructor; 43521 43522 var json; 43523 43524 // derived classes can define a static toJSON method 43525 if ( trackType.toJSON !== undefined ) { 43526 43527 json = trackType.toJSON( track ); 43528 43529 } else { 43530 43531 // by default, we assume the data can be serialized as-is 43532 json = { 43533 43534 'name': track.name, 43535 'times': AnimationUtils.convertArray( track.times, Array ), 43536 'values': AnimationUtils.convertArray( track.values, Array ) 43537 43538 }; 43539 43540 var interpolation = track.getInterpolation(); 43541 43542 if ( interpolation !== track.DefaultInterpolation ) { 43543 43544 json.interpolation = interpolation; 43545 43546 } 43547 43548 } 43549 43550 json.type = track.ValueTypeName; // mandatory 43551 43552 return json; 43553 43554 }, 43555 43556 _getTrackTypeForValueTypeName: function ( typeName ) { 43557 43558 switch ( typeName.toLowerCase() ) { 43559 43560 case 'scalar': 43561 case 'double': 43562 case 'float': 43563 case 'number': 43564 case 'integer': 43565 43566 return NumberKeyframeTrack; 43567 43568 case 'vector': 43569 case 'vector2': 43570 case 'vector3': 43571 case 'vector4': 43572 43573 return VectorKeyframeTrack; 43574 43575 case 'color': 43576 43577 return ColorKeyframeTrack; 43578 43579 case 'quaternion': 43580 43581 return QuaternionKeyframeTrack; 43582 43583 case 'bool': 43584 case 'boolean': 43585 43586 return BooleanKeyframeTrack; 43587 43588 case 'string': 43589 43590 return StringKeyframeTrack; 43591 43592 } 43593 43594 throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName ); 43595 43596 } 43597 43598 } ); 43599 43600 Object.assign( KeyframeTrack.prototype, { 43601 43602 constructor: KeyframeTrack, 43603 43604 TimeBufferType: Float32Array, 43605 43606 ValueBufferType: Float32Array, 43607 43608 DefaultInterpolation: InterpolateLinear, 43609 43610 InterpolantFactoryMethodDiscrete: function ( result ) { 43611 43612 return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result ); 43613 43614 }, 43615 43616 InterpolantFactoryMethodLinear: function ( result ) { 43617 43618 return new LinearInterpolant( this.times, this.values, this.getValueSize(), result ); 43619 43620 }, 43621 43622 InterpolantFactoryMethodSmooth: function ( result ) { 43623 43624 return new CubicInterpolant( this.times, this.values, this.getValueSize(), result ); 43625 43626 }, 43627 43628 setInterpolation: function ( interpolation ) { 43629 43630 var factoryMethod; 43631 43632 switch ( interpolation ) { 43633 43634 case InterpolateDiscrete: 43635 43636 factoryMethod = this.InterpolantFactoryMethodDiscrete; 43637 43638 break; 43639 43640 case InterpolateLinear: 43641 43642 factoryMethod = this.InterpolantFactoryMethodLinear; 43643 43644 break; 43645 43646 case InterpolateSmooth: 43647 43648 factoryMethod = this.InterpolantFactoryMethodSmooth; 43649 43650 break; 43651 43652 } 43653 43654 if ( factoryMethod === undefined ) { 43655 43656 var message = "unsupported interpolation for " + 43657 this.ValueTypeName + " keyframe track named " + this.name; 43658 43659 if ( this.createInterpolant === undefined ) { 43660 43661 // fall back to default, unless the default itself is messed up 43662 if ( interpolation !== this.DefaultInterpolation ) { 43663 43664 this.setInterpolation( this.DefaultInterpolation ); 43665 43666 } else { 43667 43668 throw new Error( message ); // fatal, in this case 43669 43670 } 43671 43672 } 43673 43674 console.warn( 'THREE.KeyframeTrack:', message ); 43675 return; 43676 43677 } 43678 43679 this.createInterpolant = factoryMethod; 43680 43681 }, 43682 43683 getInterpolation: function () { 43684 43685 switch ( this.createInterpolant ) { 43686 43687 case this.InterpolantFactoryMethodDiscrete: 43688 43689 return InterpolateDiscrete; 43690 43691 case this.InterpolantFactoryMethodLinear: 43692 43693 return InterpolateLinear; 43694 43695 case this.InterpolantFactoryMethodSmooth: 43696 43697 return InterpolateSmooth; 43698 43699 } 43700 43701 }, 43702 43703 getValueSize: function () { 43704 43705 return this.values.length / this.times.length; 43706 43707 }, 43708 43709 // move all keyframes either forwards or backwards in time 43710 shift: function ( timeOffset ) { 43711 43712 if ( timeOffset !== 0.0 ) { 43713 43714 var times = this.times; 43715 43716 for ( var i = 0, n = times.length; i !== n; ++ i ) { 43717 43718 times[ i ] += timeOffset; 43719 43720 } 43721 43722 } 43723 43724 return this; 43725 43726 }, 43727 43728 // scale all keyframe times by a factor (useful for frame <-> seconds conversions) 43729 scale: function ( timeScale ) { 43730 43731 if ( timeScale !== 1.0 ) { 43732 43733 var times = this.times; 43734 43735 for ( var i = 0, n = times.length; i !== n; ++ i ) { 43736 43737 times[ i ] *= timeScale; 43738 43739 } 43740 43741 } 43742 43743 return this; 43744 43745 }, 43746 43747 // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. 43748 // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values 43749 trim: function ( startTime, endTime ) { 43750 43751 var times = this.times, 43752 nKeys = times.length, 43753 from = 0, 43754 to = nKeys - 1; 43755 43756 while ( from !== nKeys && times[ from ] < startTime ) { 43757 43758 ++ from; 43759 43760 } 43761 43762 while ( to !== - 1 && times[ to ] > endTime ) { 43763 43764 -- to; 43765 43766 } 43767 43768 ++ to; // inclusive -> exclusive bound 43769 43770 if ( from !== 0 || to !== nKeys ) { 43771 43772 // empty tracks are forbidden, so keep at least one keyframe 43773 if ( from >= to ) to = Math.max( to, 1 ), from = to - 1; 43774 43775 var stride = this.getValueSize(); 43776 this.times = AnimationUtils.arraySlice( times, from, to ); 43777 this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride ); 43778 43779 } 43780 43781 return this; 43782 43783 }, 43784 43785 // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable 43786 validate: function () { 43787 43788 var valid = true; 43789 43790 var valueSize = this.getValueSize(); 43791 if ( valueSize - Math.floor( valueSize ) !== 0 ) { 43792 43793 console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this ); 43794 valid = false; 43795 43796 } 43797 43798 var times = this.times, 43799 values = this.values, 43800 43801 nKeys = times.length; 43802 43803 if ( nKeys === 0 ) { 43804 43805 console.error( 'THREE.KeyframeTrack: Track is empty.', this ); 43806 valid = false; 43807 43808 } 43809 43810 var prevTime = null; 43811 43812 for ( var i = 0; i !== nKeys; i ++ ) { 43813 43814 var currTime = times[ i ]; 43815 43816 if ( typeof currTime === 'number' && isNaN( currTime ) ) { 43817 43818 console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime ); 43819 valid = false; 43820 break; 43821 43822 } 43823 43824 if ( prevTime !== null && prevTime > currTime ) { 43825 43826 console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime ); 43827 valid = false; 43828 break; 43829 43830 } 43831 43832 prevTime = currTime; 43833 43834 } 43835 43836 if ( values !== undefined ) { 43837 43838 if ( AnimationUtils.isTypedArray( values ) ) { 43839 43840 for ( var i = 0, n = values.length; i !== n; ++ i ) { 43841 43842 var value = values[ i ]; 43843 43844 if ( isNaN( value ) ) { 43845 43846 console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value ); 43847 valid = false; 43848 break; 43849 43850 } 43851 43852 } 43853 43854 } 43855 43856 } 43857 43858 return valid; 43859 43860 }, 43861 43862 // removes equivalent sequential keys as common in morph target sequences 43863 // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) 43864 optimize: function () { 43865 43866 var times = this.times, 43867 values = this.values, 43868 stride = this.getValueSize(), 43869 43870 smoothInterpolation = this.getInterpolation() === InterpolateSmooth, 43871 43872 writeIndex = 1, 43873 lastIndex = times.length - 1; 43874 43875 for ( var i = 1; i < lastIndex; ++ i ) { 43876 43877 var keep = false; 43878 43879 var time = times[ i ]; 43880 var timeNext = times[ i + 1 ]; 43881 43882 // remove adjacent keyframes scheduled at the same time 43883 43884 if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) { 43885 43886 if ( ! smoothInterpolation ) { 43887 43888 // remove unnecessary keyframes same as their neighbors 43889 43890 var offset = i * stride, 43891 offsetP = offset - stride, 43892 offsetN = offset + stride; 43893 43894 for ( var j = 0; j !== stride; ++ j ) { 43895 43896 var value = values[ offset + j ]; 43897 43898 if ( value !== values[ offsetP + j ] || 43899 value !== values[ offsetN + j ] ) { 43900 43901 keep = true; 43902 break; 43903 43904 } 43905 43906 } 43907 43908 } else { 43909 43910 keep = true; 43911 43912 } 43913 43914 } 43915 43916 // in-place compaction 43917 43918 if ( keep ) { 43919 43920 if ( i !== writeIndex ) { 43921 43922 times[ writeIndex ] = times[ i ]; 43923 43924 var readOffset = i * stride, 43925 writeOffset = writeIndex * stride; 43926 43927 for ( var j = 0; j !== stride; ++ j ) { 43928 43929 values[ writeOffset + j ] = values[ readOffset + j ]; 43930 43931 } 43932 43933 } 43934 43935 ++ writeIndex; 43936 43937 } 43938 43939 } 43940 43941 // flush last keyframe (compaction looks ahead) 43942 43943 if ( lastIndex > 0 ) { 43944 43945 times[ writeIndex ] = times[ lastIndex ]; 43946 43947 for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) { 43948 43949 values[ writeOffset + j ] = values[ readOffset + j ]; 43950 43951 } 43952 43953 ++ writeIndex; 43954 43955 } 43956 43957 if ( writeIndex !== times.length ) { 43958 43959 this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); 43960 this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); 43961 43962 } 43963 43964 return this; 43965 43966 } 43967 43968 } ); 43969 43970 /** 43971 * 43972 * A Track of vectored keyframe values. 43973 * 43974 * 43975 * @author Ben Houston / http://clara.io/ 43976 * @author David Sarno / http://lighthaus.us/ 43977 * @author tschw 43978 */ 43979 43980 function VectorKeyframeTrack( name, times, values, interpolation ) { 43981 43982 KeyframeTrack.call( this, name, times, values, interpolation ); 43983 43984 } 43985 43986 VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { 43987 43988 constructor: VectorKeyframeTrack, 43989 43990 ValueTypeName: 'vector' 43991 43992 // ValueBufferType is inherited 43993 43994 // DefaultInterpolation is inherited 43995 43996 } ); 43997 43998 /** 43999 * 44000 * Reusable set of Tracks that represent an animation. 44001 * 44002 * @author Ben Houston / http://clara.io/ 44003 * @author David Sarno / http://lighthaus.us/ 44004 */ 44005 44006 function AnimationClip( name, duration, tracks ) { 44007 44008 this.name = name; 44009 this.tracks = tracks; 44010 this.duration = ( duration !== undefined ) ? duration : - 1; 44011 44012 this.uuid = _Math.generateUUID(); 44013 44014 // this means it should figure out its duration by scanning the tracks 44015 if ( this.duration < 0 ) { 44016 44017 this.resetDuration(); 44018 44019 } 44020 44021 this.optimize(); 44022 44023 } 44024 44025 Object.assign( AnimationClip, { 44026 44027 parse: function ( json ) { 44028 44029 var tracks = [], 44030 jsonTracks = json.tracks, 44031 frameTime = 1.0 / ( json.fps || 1.0 ); 44032 44033 for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { 44034 44035 tracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) ); 44036 44037 } 44038 44039 return new AnimationClip( json.name, json.duration, tracks ); 44040 44041 }, 44042 44043 toJSON: function ( clip ) { 44044 44045 var tracks = [], 44046 clipTracks = clip.tracks; 44047 44048 var json = { 44049 44050 'name': clip.name, 44051 'duration': clip.duration, 44052 'tracks': tracks, 44053 'uuid': clip.uuid 44054 44055 }; 44056 44057 for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { 44058 44059 tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) ); 44060 44061 } 44062 44063 return json; 44064 44065 }, 44066 44067 CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) { 44068 44069 var numMorphTargets = morphTargetSequence.length; 44070 var tracks = []; 44071 44072 for ( var i = 0; i < numMorphTargets; i ++ ) { 44073 44074 var times = []; 44075 var values = []; 44076 44077 times.push( 44078 ( i + numMorphTargets - 1 ) % numMorphTargets, 44079 i, 44080 ( i + 1 ) % numMorphTargets ); 44081 44082 values.push( 0, 1, 0 ); 44083 44084 var order = AnimationUtils.getKeyframeOrder( times ); 44085 times = AnimationUtils.sortedArray( times, 1, order ); 44086 values = AnimationUtils.sortedArray( values, 1, order ); 44087 44088 // if there is a key at the first frame, duplicate it as the 44089 // last frame as well for perfect loop. 44090 if ( ! noLoop && times[ 0 ] === 0 ) { 44091 44092 times.push( numMorphTargets ); 44093 values.push( values[ 0 ] ); 44094 44095 } 44096 44097 tracks.push( 44098 new NumberKeyframeTrack( 44099 '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', 44100 times, values 44101 ).scale( 1.0 / fps ) ); 44102 44103 } 44104 44105 return new AnimationClip( name, - 1, tracks ); 44106 44107 }, 44108 44109 findByName: function ( objectOrClipArray, name ) { 44110 44111 var clipArray = objectOrClipArray; 44112 44113 if ( ! Array.isArray( objectOrClipArray ) ) { 44114 44115 var o = objectOrClipArray; 44116 clipArray = o.geometry && o.geometry.animations || o.animations; 44117 44118 } 44119 44120 for ( var i = 0; i < clipArray.length; i ++ ) { 44121 44122 if ( clipArray[ i ].name === name ) { 44123 44124 return clipArray[ i ]; 44125 44126 } 44127 44128 } 44129 44130 return null; 44131 44132 }, 44133 44134 CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) { 44135 44136 var animationToMorphTargets = {}; 44137 44138 // tested with https://regex101.com/ on trick sequences 44139 // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 44140 var pattern = /^([\w-]*?)([\d]+)$/; 44141 44142 // sort morph target names into animation groups based 44143 // patterns like Walk_001, Walk_002, Run_001, Run_002 44144 for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { 44145 44146 var morphTarget = morphTargets[ i ]; 44147 var parts = morphTarget.name.match( pattern ); 44148 44149 if ( parts && parts.length > 1 ) { 44150 44151 var name = parts[ 1 ]; 44152 44153 var animationMorphTargets = animationToMorphTargets[ name ]; 44154 if ( ! animationMorphTargets ) { 44155 44156 animationToMorphTargets[ name ] = animationMorphTargets = []; 44157 44158 } 44159 44160 animationMorphTargets.push( morphTarget ); 44161 44162 } 44163 44164 } 44165 44166 var clips = []; 44167 44168 for ( var name in animationToMorphTargets ) { 44169 44170 clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) ); 44171 44172 } 44173 44174 return clips; 44175 44176 }, 44177 44178 // parse the animation.hierarchy format 44179 parseAnimation: function ( animation, bones ) { 44180 44181 if ( ! animation ) { 44182 44183 console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' ); 44184 return null; 44185 44186 } 44187 44188 var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) { 44189 44190 // only return track if there are actually keys. 44191 if ( animationKeys.length !== 0 ) { 44192 44193 var times = []; 44194 var values = []; 44195 44196 AnimationUtils.flattenJSON( animationKeys, times, values, propertyName ); 44197 44198 // empty keys are filtered out, so check again 44199 if ( times.length !== 0 ) { 44200 44201 destTracks.push( new trackType( trackName, times, values ) ); 44202 44203 } 44204 44205 } 44206 44207 }; 44208 44209 var tracks = []; 44210 44211 var clipName = animation.name || 'default'; 44212 // automatic length determination in AnimationClip. 44213 var duration = animation.length || - 1; 44214 var fps = animation.fps || 30; 44215 44216 var hierarchyTracks = animation.hierarchy || []; 44217 44218 for ( var h = 0; h < hierarchyTracks.length; h ++ ) { 44219 44220 var animationKeys = hierarchyTracks[ h ].keys; 44221 44222 // skip empty tracks 44223 if ( ! animationKeys || animationKeys.length === 0 ) continue; 44224 44225 // process morph targets 44226 if ( animationKeys[ 0 ].morphTargets ) { 44227 44228 // figure out all morph targets used in this track 44229 var morphTargetNames = {}; 44230 44231 for ( var k = 0; k < animationKeys.length; k ++ ) { 44232 44233 if ( animationKeys[ k ].morphTargets ) { 44234 44235 for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) { 44236 44237 morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1; 44238 44239 } 44240 44241 } 44242 44243 } 44244 44245 // create a track for each morph target with all zero 44246 // morphTargetInfluences except for the keys in which 44247 // the morphTarget is named. 44248 for ( var morphTargetName in morphTargetNames ) { 44249 44250 var times = []; 44251 var values = []; 44252 44253 for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) { 44254 44255 var animationKey = animationKeys[ k ]; 44256 44257 times.push( animationKey.time ); 44258 values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); 44259 44260 } 44261 44262 tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); 44263 44264 } 44265 44266 duration = morphTargetNames.length * ( fps || 1.0 ); 44267 44268 } else { 44269 44270 // ...assume skeletal animation 44271 44272 var boneName = '.bones[' + bones[ h ].name + ']'; 44273 44274 addNonemptyTrack( 44275 VectorKeyframeTrack, boneName + '.position', 44276 animationKeys, 'pos', tracks ); 44277 44278 addNonemptyTrack( 44279 QuaternionKeyframeTrack, boneName + '.quaternion', 44280 animationKeys, 'rot', tracks ); 44281 44282 addNonemptyTrack( 44283 VectorKeyframeTrack, boneName + '.scale', 44284 animationKeys, 'scl', tracks ); 44285 44286 } 44287 44288 } 44289 44290 if ( tracks.length === 0 ) { 44291 44292 return null; 44293 44294 } 44295 44296 var clip = new AnimationClip( clipName, duration, tracks ); 44297 44298 return clip; 44299 44300 } 44301 44302 } ); 44303 44304 Object.assign( AnimationClip.prototype, { 44305 44306 resetDuration: function () { 44307 44308 var tracks = this.tracks, duration = 0; 44309 44310 for ( var i = 0, n = tracks.length; i !== n; ++ i ) { 44311 44312 var track = this.tracks[ i ]; 44313 44314 duration = Math.max( duration, track.times[ track.times.length - 1 ] ); 44315 44316 } 44317 44318 this.duration = duration; 44319 44320 }, 44321 44322 trim: function () { 44323 44324 for ( var i = 0; i < this.tracks.length; i ++ ) { 44325 44326 this.tracks[ i ].trim( 0, this.duration ); 44327 44328 } 44329 44330 return this; 44331 44332 }, 44333 44334 optimize: function () { 44335 44336 for ( var i = 0; i < this.tracks.length; i ++ ) { 44337 44338 this.tracks[ i ].optimize(); 44339 44340 } 44341 44342 return this; 44343 44344 } 44345 44346 } ); 44347 44348 /** 44349 * @author mrdoob / http://mrdoob.com/ 44350 */ 44351 44352 function MaterialLoader( manager ) { 44353 44354 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 44355 this.textures = {}; 44356 44357 } 44358 44359 Object.assign( MaterialLoader.prototype, { 44360 44361 load: function ( url, onLoad, onProgress, onError ) { 44362 44363 var scope = this; 44364 44365 var loader = new FileLoader( scope.manager ); 44366 loader.load( url, function ( text ) { 44367 44368 onLoad( scope.parse( JSON.parse( text ) ) ); 44369 44370 }, onProgress, onError ); 44371 44372 }, 44373 44374 setTextures: function ( value ) { 44375 44376 this.textures = value; 44377 44378 }, 44379 44380 parse: function ( json ) { 44381 44382 var textures = this.textures; 44383 44384 function getTexture( name ) { 44385 44386 if ( textures[ name ] === undefined ) { 44387 44388 console.warn( 'THREE.MaterialLoader: Undefined texture', name ); 44389 44390 } 44391 44392 return textures[ name ]; 44393 44394 } 44395 44396 var material = new Materials[ json.type ](); 44397 44398 if ( json.uuid !== undefined ) material.uuid = json.uuid; 44399 if ( json.name !== undefined ) material.name = json.name; 44400 if ( json.color !== undefined ) material.color.setHex( json.color ); 44401 if ( json.roughness !== undefined ) material.roughness = json.roughness; 44402 if ( json.metalness !== undefined ) material.metalness = json.metalness; 44403 if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); 44404 if ( json.specular !== undefined ) material.specular.setHex( json.specular ); 44405 if ( json.shininess !== undefined ) material.shininess = json.shininess; 44406 if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; 44407 if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; 44408 if ( json.uniforms !== undefined ) material.uniforms = json.uniforms; 44409 if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader; 44410 if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader; 44411 if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; 44412 if ( json.fog !== undefined ) material.fog = json.fog; 44413 if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; 44414 if ( json.blending !== undefined ) material.blending = json.blending; 44415 if ( json.side !== undefined ) material.side = json.side; 44416 if ( json.opacity !== undefined ) material.opacity = json.opacity; 44417 if ( json.transparent !== undefined ) material.transparent = json.transparent; 44418 if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; 44419 if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; 44420 if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; 44421 if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; 44422 if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; 44423 if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; 44424 if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; 44425 if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; 44426 44427 if ( json.rotation !== undefined ) material.rotation = json.rotation; 44428 44429 if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; 44430 if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; 44431 if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; 44432 if ( json.scale !== undefined ) material.scale = json.scale; 44433 44434 if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; 44435 if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; 44436 if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; 44437 44438 if ( json.skinning !== undefined ) material.skinning = json.skinning; 44439 if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; 44440 if ( json.dithering !== undefined ) material.dithering = json.dithering; 44441 44442 if ( json.visible !== undefined ) material.visible = json.visible; 44443 if ( json.userData !== undefined ) material.userData = json.userData; 44444 44445 // Deprecated 44446 44447 if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading 44448 44449 // for PointsMaterial 44450 44451 if ( json.size !== undefined ) material.size = json.size; 44452 if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; 44453 44454 // maps 44455 44456 if ( json.map !== undefined ) material.map = getTexture( json.map ); 44457 44458 if ( json.alphaMap !== undefined ) { 44459 44460 material.alphaMap = getTexture( json.alphaMap ); 44461 material.transparent = true; 44462 44463 } 44464 44465 if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); 44466 if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; 44467 44468 if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); 44469 if ( json.normalScale !== undefined ) { 44470 44471 var normalScale = json.normalScale; 44472 44473 if ( Array.isArray( normalScale ) === false ) { 44474 44475 // Blender exporter used to export a scalar. See #7459 44476 44477 normalScale = [ normalScale, normalScale ]; 44478 44479 } 44480 44481 material.normalScale = new Vector2().fromArray( normalScale ); 44482 44483 } 44484 44485 if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap ); 44486 if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale; 44487 if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias; 44488 44489 if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); 44490 if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); 44491 44492 if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); 44493 if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; 44494 44495 if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); 44496 44497 if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); 44498 44499 if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; 44500 44501 if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); 44502 if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; 44503 44504 if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); 44505 if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; 44506 44507 if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); 44508 44509 return material; 44510 44511 } 44512 44513 } ); 44514 44515 /** 44516 * @author mrdoob / http://mrdoob.com/ 44517 */ 44518 44519 function BufferGeometryLoader( manager ) { 44520 44521 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 44522 44523 } 44524 44525 Object.assign( BufferGeometryLoader.prototype, { 44526
44527 load: function ( url, onLoad, onProgress, onError ) { 44528 44529 var scope = this; 44530 44531 var loader = new FileLoader( scope.manager ); 44532 loader.load( url, function ( text ) { 44533 44534 onLoad( scope.parse( JSON.parse( text ) ) ); 44535 44536 }, onProgress, onError ); 44537 44538 }, 44539 44540 parse: function ( json ) { 44541 44542 var geometry = new BufferGeometry(); 44543 44544 var index = json.data.index; 44545 44546 if ( index !== undefined ) { 44547 44548 var typedArray = new TYPED_ARRAYS[ index.type ]( index.array ); 44549 geometry.setIndex( new BufferAttribute( typedArray, 1 ) ); 44550 44551 } 44552 44553 var attributes = json.data.attributes; 44554 44555 for ( var key in attributes ) { 44556 44557 var attribute = attributes[ key ]; 44558 var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); 44559 44560 geometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) ); 44561 44562 } 44563 44564 var groups = json.data.groups || json.data.drawcalls || json.data.offsets; 44565 44566 if ( groups !== undefined ) { 44567 44568 for ( var i = 0, n = groups.length; i !== n; ++ i ) { 44569 44570 var group = groups[ i ]; 44571 44572 geometry.addGroup( group.start, group.count, group.materialIndex ); 44573 44574 } 44575 44576 } 44577 44578 var boundingSphere = json.data.boundingSphere; 44579 44580 if ( boundingSphere !== undefined ) { 44581 44582 var center = new Vector3(); 44583 44584 if ( boundingSphere.center !== undefined ) { 44585 44586 center.fromArray( boundingSphere.center ); 44587 44588 } 44589 44590 geometry.boundingSphere = new Sphere( center, boundingSphere.radius ); 44591 44592 } 44593 44594 return geometry; 44595 44596 } 44597 44598 } ); 44599 44600 var TYPED_ARRAYS = { 44601 Int8Array: Int8Array, 44602 Uint8Array: Uint8Array, 44603 // Workaround for IE11 pre KB2929437. See #11440 44604 Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array, 44605 Int16Array: Int16Array, 44606 Uint16Array: Uint16Array, 44607 Int32Array: Int32Array, 44608 Uint32Array: Uint32Array, 44609 Float32Array: Float32Array, 44610 Float64Array: Float64Array 44611 }; 44612 44613 /** 44614 * @author alteredq / http://alteredqualia.com/ 44615 */ 44616 44617 function Loader() {} 44618 44619 Loader.Handlers = { 44620 44621 handlers: [], 44622 44623 add: function ( regex, loader ) { 44624 44625 this.handlers.push( regex, loader ); 44626 44627 }, 44628 44629 get: function ( file ) { 44630 44631 var handlers = this.handlers; 44632 44633 for ( var i = 0, l = handlers.length; i < l; i += 2 ) { 44634 44635 var regex = handlers[ i ]; 44636 var loader = handlers[ i + 1 ]; 44637 44638 if ( regex.test( file ) ) { 44639 44640 return loader; 44641 44642 } 44643 44644 } 44645 44646 return null; 44647 44648 } 44649 44650 }; 44651 44652 Object.assign( Loader.prototype, { 44653
44654 crossOrigin: undefined, 44655 44656 onLoadStart: function () {}, 44657 44658 onLoadProgress: function () {}, 44659 44660 onLoadComplete: function () {}, 44661 44662 initMaterials: function ( materials, texturePath, crossOrigin ) { 44663 44664 var array = []; 44665 44666 for ( var i = 0; i < materials.length; ++ i ) { 44667 44668 array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); 44669 44670 } 44671 44672 return array; 44673 44674 }, 44675 44676 createMaterial: ( function () { 44677 44678 var BlendingMode = { 44679 NoBlending: NoBlending, 44680 NormalBlending: NormalBlending, 44681 AdditiveBlending: AdditiveBlending, 44682 SubtractiveBlending: SubtractiveBlending, 44683 MultiplyBlending: MultiplyBlending, 44684 CustomBlending: CustomBlending 44685 }; 44686 44687 var color = new Color(); 44688 var textureLoader = new TextureLoader(); 44689 var materialLoader = new MaterialLoader(); 44690 44691 return function createMaterial( m, texturePath, crossOrigin ) { 44692 44693 // convert from old material format 44694 44695 var textures = {}; 44696 44697 function loadTexture( path, repeat, offset, wrap, anisotropy ) { 44698 44699 var fullPath = texturePath + path; 44700 var loader = Loader.Handlers.get( fullPath ); 44701 44702 var texture; 44703 44704 if ( loader !== null ) { 44705 44706 texture = loader.load( fullPath ); 44707 44708 } else { 44709 44710 textureLoader.setCrossOrigin( crossOrigin ); 44711 texture = textureLoader.load( fullPath ); 44712 44713 } 44714 44715 if ( repeat !== undefined ) { 44716 44717 texture.repeat.fromArray( repeat ); 44718 44719 if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; 44720 if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; 44721 44722 } 44723 44724 if ( offset !== undefined ) { 44725 44726 texture.offset.fromArray( offset ); 44727 44728 } 44729 44730 if ( wrap !== undefined ) { 44731 44732 if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; 44733 if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; 44734 44735 if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; 44736 if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; 44737 44738 } 44739 44740 if ( anisotropy !== undefined ) { 44741 44742 texture.anisotropy = anisotropy; 44743 44744 } 44745 44746 var uuid = _Math.generateUUID(); 44747 44748 textures[ uuid ] = texture; 44749 44750 return uuid; 44751 44752 } 44753 44754 // 44755 44756 var json = { 44757 uuid: _Math.generateUUID(), 44758 type: 'MeshLambertMaterial' 44759 }; 44760 44761 for ( var name in m ) { 44762 44763 var value = m[ name ]; 44764 44765 switch ( name ) { 44766 44767 case 'DbgColor': 44768 case 'DbgIndex': 44769 case 'opticalDensity': 44770 case 'illumination': 44771 break; 44772 case 'DbgName': 44773 json.name = value; 44774 break; 44775 case 'blending': 44776 json.blending = BlendingMode[ value ]; 44777 break; 44778 case 'colorAmbient': 44779 case 'mapAmbient': 44780 console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); 44781 break; 44782 case 'colorDiffuse': 44783 json.color = color.fromArray( value ).getHex(); 44784 break; 44785 case 'colorSpecular': 44786 json.specular = color.fromArray( value ).getHex(); 44787 break; 44788 case 'colorEmissive': 44789 json.emissive = color.fromArray( value ).getHex(); 44790 break; 44791 case 'specularCoef': 44792 json.shininess = value; 44793 break; 44794 case 'shading': 44795 if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; 44796 if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; 44797 if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; 44798 break; 44799 case 'mapDiffuse': 44800 json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); 44801 break; 44802 case 'mapDiffuseRepeat': 44803 case 'mapDiffuseOffset': 44804 case 'mapDiffuseWrap': 44805 case 'mapDiffuseAnisotropy': 44806 break; 44807 case 'mapEmissive': 44808 json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy ); 44809 break; 44810 case 'mapEmissiveRepeat': 44811 case 'mapEmissiveOffset': 44812 case 'mapEmissiveWrap': 44813 case 'mapEmissiveAnisotropy': 44814 break; 44815 case 'mapLight': 44816 json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); 44817 break; 44818 case 'mapLightRepeat': 44819 case 'mapLightOffset': 44820 case 'mapLightWrap': 44821 case 'mapLightAnisotropy': 44822 break; 44823 case 'mapAO': 44824 json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy ); 44825 break; 44826 case 'mapAORepeat': 44827 case 'mapAOOffset': 44828 case 'mapAOWrap': 44829 case 'mapAOAnisotropy': 44830 break; 44831 case 'mapBump': 44832 json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); 44833 break; 44834 case 'mapBumpScale': 44835 json.bumpScale = value; 44836 break; 44837 case 'mapBumpRepeat': 44838 case 'mapBumpOffset': 44839 case 'mapBumpWrap': 44840 case 'mapBumpAnisotropy': 44841 break; 44842 case 'mapNormal': 44843 json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); 44844 break; 44845 case 'mapNormalFactor': 44846 json.normalScale = value; 44847 break; 44848 case 'mapNormalRepeat': 44849 case 'mapNormalOffset': 44850 case 'mapNormalWrap': 44851 case 'mapNormalAnisotropy': 44852 break; 44853 case 'mapSpecular': 44854 json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); 44855 break; 44856 case 'mapSpecularRepeat': 44857 case 'mapSpecularOffset': 44858 case 'mapSpecularWrap': 44859 case 'mapSpecularAnisotropy': 44860 break; 44861 case 'mapMetalness': 44862 json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy ); 44863 break; 44864 case 'mapMetalnessRepeat': 44865 case 'mapMetalnessOffset': 44866 case 'mapMetalnessWrap': 44867 case 'mapMetalnessAnisotropy': 44868 break; 44869 case 'mapRoughness': 44870 json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy ); 44871 break; 44872 case 'mapRoughnessRepeat': 44873 case 'mapRoughnessOffset': 44874 case 'mapRoughnessWrap': 44875 case 'mapRoughnessAnisotropy': 44876 break; 44877 case 'mapAlpha':
44878 json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy ); 44879 break; 44880 case 'mapAlphaRepeat': 44881 case 'mapAlphaOffset': 44882 case 'mapAlphaWrap': 44883 case 'mapAlphaAnisotropy': 44884 break; 44885 case 'flipSided': 44886 json.side = BackSide; 44887 break; 44888 case 'doubleSided': 44889 json.side = DoubleSide; 44890 break; 44891 case 'transparency': 44892 console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); 44893 json.opacity = value; 44894 break; 44895 case 'depthTest': 44896 case 'depthWrite': 44897 case 'colorWrite': 44898 case 'opacity': 44899 case 'reflectivity': 44900 case 'transparent': 44901 case 'visible': 44902 case 'wireframe': 44903 json[ name ] = value; 44904 break; 44905 case 'vertexColors': 44906 if ( value === true ) json.vertexColors = VertexColors; 44907 if ( value === 'face' ) json.vertexColors = FaceColors; 44908 break; 44909 default: 44910 console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); 44911 break; 44912 44913 } 44914 44915 } 44916 44917 if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; 44918 if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; 44919 44920 if ( json.opacity < 1 ) json.transparent = true; 44921 44922 materialLoader.setTextures( textures ); 44923 44924 return materialLoader.parse( json ); 44925 44926 }; 44927 44928 } )() 44929 44930 } ); 44931 44932 /** 44933 * @author Don McCurdy / https://www.donmccurdy.com 44934 */ 44935 44936 var LoaderUtils = { 44937 44938 decodeText: function ( array ) { 44939 44940 if ( typeof TextDecoder !== 'undefined' ) { 44941 44942 return new TextDecoder().decode( array ); 44943 44944 } 44945 44946 // Avoid the String.fromCharCode.apply(null, array) shortcut, which 44947 // throws a "maximum call stack size exceeded" error for large arrays. 44948 44949 var s = ''; 44950 44951 for ( var i = 0, il = array.length; i < il; i ++ ) { 44952 44953 // Implicitly assumes little-endian. 44954 s += String.fromCharCode( array[ i ] ); 44955 44956 } 44957 44958 // Merges multi-byte utf-8 characters. 44959 return decodeURIComponent( escape( s ) ); 44960 44961 }, 44962 44963 extractUrlBase: function ( url ) { 44964 44965 var index = url.lastIndexOf( '/' ); 44966 44967 if ( index === - 1 ) return './'; 44968 44969 return url.substr( 0, index + 1 ); 44970 44971 } 44972 44973 }; 44974 44975 /** 44976 * @author mrdoob / http://mrdoob.com/ 44977 * @author alteredq / http://alteredqualia.com/ 44978 */ 44979 44980 function JSONLoader( manager ) { 44981 44982 if ( typeof manager === 'boolean' ) { 44983 44984 console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' ); 44985 manager = undefined; 44986 44987 } 44988 44989 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 44990 44991 this.withCredentials = false; 44992 44993 } 44994 44995 Object.assign( JSONLoader.prototype, { 44996
vendor: 4,715 bytes, lines 44997-45214
44997 load: function ( url, onLoad, onProgress, onError ) { 44998 44999 var scope = this; 45000 45001 var texturePath = this.texturePath && ( typeof this.texturePath === 'string' ) ? this.texturePath : LoaderUtils.extractUrlBase( url ); 45002 45003 var loader = new FileLoader( this.manager ); 45004 loader.setWithCredentials( this.withCredentials ); 45005 loader.load( url, function ( text ) { 45006 45007 var json = JSON.parse( text ); 45008 var metadata = json.metadata; 45009 45010 if ( metadata !== undefined ) { 45011 45012 var type = metadata.type; 45013 45014 if ( type !== undefined ) { 45015 45016 if ( type.toLowerCase() === 'object' ) { 45017 45018 console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); 45019 return; 45020 45021 } 45022 45023 } 45024 45025 } 45026 45027 var object = scope.parse( json, texturePath ); 45028 onLoad( object.geometry, object.materials ); 45029 45030 }, onProgress, onError ); 45031 45032 }, 45033 45034 setTexturePath: function ( value ) { 45035 45036 this.texturePath = value; 45037 45038 }, 45039 45040 parse: ( function () { 45041 45042 function parseModel( json, geometry ) { 45043 45044 function isBitSet( value, position ) { 45045 45046 return value & ( 1 << position ); 45047 45048 } 45049 45050 var i, j, fi, 45051 45052 offset, zLength, 45053 45054 colorIndex, normalIndex, uvIndex, materialIndex, 45055 45056 type, 45057 isQuad, 45058 hasMaterial, 45059 hasFaceVertexUv, 45060 hasFaceNormal, hasFaceVertexNormal, 45061 hasFaceColor, hasFaceVertexColor, 45062 45063 vertex, face, faceA, faceB, hex, normal, 45064 45065 uvLayer, uv, u, v, 45066 45067 faces = json.faces, 45068 vertices = json.vertices, 45069 normals = json.normals, 45070 colors = json.colors, 45071 45072 scale = json.scale, 45073 45074 nUvLayers = 0; 45075 45076 45077 if ( json.uvs !== undefined ) { 45078 45079 // disregard empty arrays 45080 45081 for ( i = 0; i < json.uvs.length; i ++ ) { 45082 45083 if ( json.uvs[ i ].length ) nUvLayers ++; 45084 45085 } 45086 45087 for ( i = 0; i < nUvLayers; i ++ ) { 45088 45089 geometry.faceVertexUvs[ i ] = []; 45090 45091 } 45092 45093 } 45094 45095 offset = 0; 45096 zLength = vertices.length; 45097 45098 while ( offset < zLength ) { 45099 45100 vertex = new Vector3(); 45101 45102 vertex.x = vertices[ offset ++ ] * scale; 45103 vertex.y = vertices[ offset ++ ] * scale; 45104 vertex.z = vertices[ offset ++ ] * scale; 45105 45106 geometry.vertices.push( vertex ); 45107 45108 } 45109 45110 offset = 0; 45111 zLength = faces.length; 45112 45113 while ( offset < zLength ) { 45114 45115 type = faces[ offset ++ ]; 45116 45117 isQuad = isBitSet( type, 0 ); 45118 hasMaterial = isBitSet( type, 1 ); 45119 hasFaceVertexUv = isBitSet( type, 3 ); 45120 hasFaceNormal = isBitSet( type, 4 ); 45121 hasFaceVertexNormal = isBitSet( type, 5 ); 45122 hasFaceColor = isBitSet( type, 6 ); 45123 hasFaceVertexColor = isBitSet( type, 7 ); 45124 45125 // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); 45126 45127 if ( isQuad ) { 45128 45129 faceA = new Face3(); 45130 faceA.a = faces[ offset ]; 45131 faceA.b = faces[ offset + 1 ]; 45132 faceA.c = faces[ offset + 3 ]; 45133 45134 faceB = new Face3(); 45135 faceB.a = faces[ offset + 1 ]; 45136 faceB.b = faces[ offset + 2 ]; 45137 faceB.c = faces[ offset + 3 ]; 45138 45139 offset += 4; 45140 45141 if ( hasMaterial ) { 45142 45143 materialIndex = faces[ offset ++ ]; 45144 faceA.materialIndex = materialIndex; 45145 faceB.materialIndex = materialIndex; 45146 45147 } 45148 45149 // to get face <=> uv index correspondence 45150 45151 fi = geometry.faces.length; 45152 45153 if ( hasFaceVertexUv ) { 45154 45155 for ( i = 0; i < nUvLayers; i ++ ) { 45156 45157 uvLayer = json.uvs[ i ]; 45158 45159 geometry.faceVertexUvs[ i ][ fi ] = []; 45160 geometry.faceVertexUvs[ i ][ fi + 1 ] = []; 45161 45162 for ( j = 0; j < 4; j ++ ) { 45163 45164 uvIndex = faces[ offset ++ ]; 45165 45166 u = uvLayer[ uvIndex * 2 ]; 45167 v = uvLayer[ uvIndex * 2 + 1 ]; 45168 45169 uv = new Vector2( u, v ); 45170 45171 if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv ); 45172 if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv ); 45173 45174 } 45175 45176 } 45177 45178 } 45179 45180 if ( hasFaceNormal ) { 45181 45182 normalIndex = faces[ offset ++ ] * 3; 45183 45184 faceA.normal.set( 45185 normals[ normalIndex ++ ], 45186 normals[ normalIndex ++ ], 45187 normals[ normalIndex ] 45188 ); 45189 45190 faceB.normal.copy( faceA.normal ); 45191 45192 } 45193 45194 if ( hasFaceVertexNormal ) { 45195 45196 for ( i = 0; i < 4; i ++ ) { 45197 45198 normalIndex = faces[ offset ++ ] * 3; 45199 45200 normal = new Vector3( 45201 normals[ normalIndex ++ ], 45202 normals[ normalIndex ++ ], 45203 normals[ normalIndex ] 45204 ); 45205 45206 45207 if ( i !== 2 ) faceA.vertexNormals.push( normal ); 45208 if ( i !== 0 ) faceB.vertexNormals.push( normal ); 45209 45210 } 45211 45212 } 45213 45214
45215 if ( hasFaceColor ) { 45216 45217 colorIndex = faces[ offset ++ ]; 45218 hex = colors[ colorIndex ]; 45219 45220 faceA.color.setHex( hex ); 45221 faceB.color.setHex( hex ); 45222 45223 } 45224 45225 45226 if ( hasFaceVertexColor ) { 45227 45228 for ( i = 0; i < 4; i ++ ) { 45229 45230 colorIndex = faces[ offset ++ ]; 45231 hex = colors[ colorIndex ]; 45232 45233 if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) ); 45234 if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) ); 45235 45236 } 45237 45238 } 45239 45240 geometry.faces.push( faceA ); 45241 geometry.faces.push( faceB ); 45242 45243 } else { 45244 45245 face = new Face3(); 45246 face.a = faces[ offset ++ ]; 45247 face.b = faces[ offset ++ ]; 45248 face.c = faces[ offset ++ ]; 45249 45250 if ( hasMaterial ) { 45251 45252 materialIndex = faces[ offset ++ ]; 45253 face.materialIndex = materialIndex; 45254 45255 } 45256 45257 // to get face <=> uv index correspondence 45258 45259 fi = geometry.faces.length; 45260 45261 if ( hasFaceVertexUv ) { 45262 45263 for ( i = 0; i < nUvLayers; i ++ ) { 45264 45265 uvLayer = json.uvs[ i ]; 45266 45267 geometry.faceVertexUvs[ i ][ fi ] = []; 45268 45269 for ( j = 0; j < 3; j ++ ) { 45270 45271 uvIndex = faces[ offset ++ ]; 45272 45273 u = uvLayer[ uvIndex * 2 ]; 45274 v = uvLayer[ uvIndex * 2 + 1 ]; 45275 45276 uv = new Vector2( u, v ); 45277 45278 geometry.faceVertexUvs[ i ][ fi ].push( uv ); 45279 45280 } 45281 45282 } 45283 45284 } 45285 45286 if ( hasFaceNormal ) { 45287 45288 normalIndex = faces[ offset ++ ] * 3; 45289 45290 face.normal.set( 45291 normals[ normalIndex ++ ], 45292 normals[ normalIndex ++ ], 45293 normals[ normalIndex ] 45294 ); 45295 45296 } 45297 45298 if ( hasFaceVertexNormal ) { 45299 45300 for ( i = 0; i < 3; i ++ ) { 45301 45302 normalIndex = faces[ offset ++ ] * 3; 45303 45304 normal = new Vector3( 45305 normals[ normalIndex ++ ], 45306 normals[ normalIndex ++ ], 45307 normals[ normalIndex ] 45308 ); 45309 45310 face.vertexNormals.push( normal ); 45311 45312 } 45313 45314 } 45315 45316
vendor: 4,621 bytes, lines 45317-45497
45317 if ( hasFaceColor ) { 45318 45319 colorIndex = faces[ offset ++ ]; 45320 face.color.setHex( colors[ colorIndex ] ); 45321 45322 } 45323 45324 45325 if ( hasFaceVertexColor ) { 45326 45327 for ( i = 0; i < 3; i ++ ) { 45328 45329 colorIndex = faces[ offset ++ ]; 45330 face.vertexColors.push( new Color( colors[ colorIndex ] ) ); 45331 45332 } 45333 45334 } 45335 45336 geometry.faces.push( face ); 45337 45338 } 45339 45340 } 45341 45342 } 45343 45344 function parseSkin( json, geometry ) { 45345 45346 var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2; 45347 45348 if ( json.skinWeights ) { 45349 45350 for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) { 45351 45352 var x = json.skinWeights[ i ]; 45353 var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0; 45354 var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0; 45355 var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0; 45356 45357 geometry.skinWeights.push( new Vector4( x, y, z, w ) ); 45358 45359 } 45360 45361 } 45362 45363 if ( json.skinIndices ) { 45364 45365 for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) { 45366 45367 var a = json.skinIndices[ i ]; 45368 var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0; 45369 var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0; 45370 var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0; 45371 45372 geometry.skinIndices.push( new Vector4( a, b, c, d ) ); 45373 45374 } 45375 45376 } 45377 45378 geometry.bones = json.bones; 45379 45380 if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { 45381 45382 console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + 45383 geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); 45384 45385 } 45386 45387 } 45388 45389 function parseMorphing( json, geometry ) { 45390 45391 var scale = json.scale; 45392 45393 if ( json.morphTargets !== undefined ) { 45394 45395 for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) { 45396 45397 geometry.morphTargets[ i ] = {}; 45398 geometry.morphTargets[ i ].name = json.morphTargets[ i ].name; 45399 geometry.morphTargets[ i ].vertices = []; 45400 45401 var dstVertices = geometry.morphTargets[ i ].vertices; 45402 var srcVertices = json.morphTargets[ i ].vertices; 45403 45404 for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) { 45405 45406 var vertex = new Vector3(); 45407 vertex.x = srcVertices[ v ] * scale; 45408 vertex.y = srcVertices[ v + 1 ] * scale; 45409 vertex.z = srcVertices[ v + 2 ] * scale; 45410 45411 dstVertices.push( vertex ); 45412 45413 } 45414 45415 } 45416 45417 } 45418 45419 if ( json.morphColors !== undefined && json.morphColors.length > 0 ) { 45420 45421 console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' ); 45422 45423 var faces = geometry.faces; 45424 var morphColors = json.morphColors[ 0 ].colors; 45425 45426 for ( var i = 0, l = faces.length; i < l; i ++ ) { 45427 45428 faces[ i ].color.fromArray( morphColors, i * 3 ); 45429 45430 } 45431 45432 } 45433 45434 } 45435 45436 function parseAnimations( json, geometry ) { 45437 45438 var outputAnimations = []; 45439 45440 // parse old style Bone/Hierarchy animations 45441 var animations = []; 45442 45443 if ( json.animation !== undefined ) { 45444 45445 animations.push( json.animation ); 45446 45447 } 45448 45449 if ( json.animations !== undefined ) { 45450 45451 if ( json.animations.length ) { 45452 45453 animations = animations.concat( json.animations ); 45454 45455 } else { 45456 45457 animations.push( json.animations ); 45458 45459 } 45460 45461 } 45462 45463 for ( var i = 0; i < animations.length; i ++ ) { 45464 45465 var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones ); 45466 if ( clip ) outputAnimations.push( clip ); 45467 45468 } 45469 45470 // parse implicit morph animations 45471 if ( geometry.morphTargets ) { 45472 45473 // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary. 45474 var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 ); 45475 outputAnimations = outputAnimations.concat( morphAnimationClips ); 45476 45477 } 45478 45479 if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations; 45480 45481 } 45482 45483 return function parse( json, texturePath ) { 45484 45485 if ( json.data !== undefined ) { 45486 45487 // Geometry 4.0 spec 45488 json = json.data; 45489 45490 } 45491 45492 if ( json.scale !== undefined ) { 45493 45494 json.scale = 1.0 / json.scale; 45495 45496 } else { 45497
vendor: 20,413 bytes, lines 45498-46423
45498 json.scale = 1.0; 45499 45500 } 45501 45502 var geometry = new Geometry(); 45503 45504 parseModel( json, geometry ); 45505 parseSkin( json, geometry ); 45506 parseMorphing( json, geometry ); 45507 parseAnimations( json, geometry ); 45508 45509 geometry.computeFaceNormals(); 45510 geometry.computeBoundingSphere(); 45511 45512 if ( json.materials === undefined || json.materials.length === 0 ) { 45513 45514 return { geometry: geometry }; 45515 45516 } else { 45517 45518 var materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin ); 45519 45520 return { geometry: geometry, materials: materials }; 45521 45522 } 45523 45524 }; 45525 45526 } )() 45527 45528 } ); 45529 45530 /** 45531 * @author mrdoob / http://mrdoob.com/ 45532 */ 45533 45534 function ObjectLoader( manager ) { 45535 45536 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 45537 this.texturePath = ''; 45538 45539 } 45540 45541 Object.assign( ObjectLoader.prototype, { 45542 45543 load: function ( url, onLoad, onProgress, onError ) { 45544 45545 if ( this.texturePath === '' ) { 45546 45547 this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); 45548 45549 } 45550 45551 var scope = this; 45552 45553 var loader = new FileLoader( scope.manager ); 45554 loader.load( url, function ( text ) { 45555 45556 var json = null; 45557 45558 try { 45559 45560 json = JSON.parse( text ); 45561 45562 } catch ( error ) { 45563 45564 if ( onError !== undefined ) onError( error ); 45565 45566 console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); 45567 45568 return; 45569 45570 } 45571 45572 var metadata = json.metadata; 45573 45574 if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { 45575 45576 console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' ); 45577 return; 45578 45579 } 45580 45581 scope.parse( json, onLoad ); 45582 45583 }, onProgress, onError ); 45584 45585 }, 45586 45587 setTexturePath: function ( value ) { 45588 45589 this.texturePath = value; 45590 return this; 45591 45592 }, 45593 45594 setCrossOrigin: function ( value ) { 45595 45596 this.crossOrigin = value; 45597 return this; 45598 45599 }, 45600 45601 parse: function ( json, onLoad ) { 45602 45603 var shapes = this.parseShape( json.shapes ); 45604 var geometries = this.parseGeometries( json.geometries, shapes ); 45605 45606 var images = this.parseImages( json.images, function () { 45607 45608 if ( onLoad !== undefined ) onLoad( object ); 45609 45610 } ); 45611 45612 var textures = this.parseTextures( json.textures, images ); 45613 var materials = this.parseMaterials( json.materials, textures ); 45614 45615 var object = this.parseObject( json.object, geometries, materials ); 45616 45617 if ( json.animations ) { 45618 45619 object.animations = this.parseAnimations( json.animations ); 45620 45621 } 45622 45623 if ( json.images === undefined || json.images.length === 0 ) { 45624 45625 if ( onLoad !== undefined ) onLoad( object ); 45626 45627 } 45628 45629 return object; 45630 45631 }, 45632 45633 parseShape: function ( json ) { 45634 45635 var shapes = {}; 45636 45637 if ( json !== undefined ) { 45638 45639 for ( var i = 0, l = json.length; i < l; i ++ ) { 45640 45641 var shape = new Shape().fromJSON( json[ i ] ); 45642 45643 shapes[ shape.uuid ] = shape; 45644 45645 } 45646 45647 } 45648 45649 return shapes; 45650 45651 }, 45652 45653 parseGeometries: function ( json, shapes ) { 45654 45655 var geometries = {}; 45656 45657 if ( json !== undefined ) { 45658 45659 var geometryLoader = new JSONLoader(); 45660 var bufferGeometryLoader = new BufferGeometryLoader(); 45661 45662 for ( var i = 0, l = json.length; i < l; i ++ ) { 45663 45664 var geometry; 45665 var data = json[ i ]; 45666 45667 switch ( data.type ) { 45668 45669 case 'PlaneGeometry': 45670 case 'PlaneBufferGeometry': 45671 45672 geometry = new Geometries[ data.type ]( 45673 data.width, 45674 data.height, 45675 data.widthSegments, 45676 data.heightSegments 45677 ); 45678 45679 break; 45680 45681 case 'BoxGeometry': 45682 case 'BoxBufferGeometry': 45683 case 'CubeGeometry': // backwards compatible 45684 45685 geometry = new Geometries[ data.type ]( 45686 data.width, 45687 data.height, 45688 data.depth, 45689 data.widthSegments, 45690 data.heightSegments, 45691 data.depthSegments 45692 ); 45693 45694 break; 45695 45696 case 'CircleGeometry': 45697 case 'CircleBufferGeometry': 45698 45699 geometry = new Geometries[ data.type ]( 45700 data.radius, 45701 data.segments, 45702 data.thetaStart, 45703 data.thetaLength 45704 ); 45705 45706 break; 45707 45708 case 'CylinderGeometry': 45709 case 'CylinderBufferGeometry': 45710 45711 geometry = new Geometries[ data.type ]( 45712 data.radiusTop, 45713 data.radiusBottom, 45714 data.height, 45715 data.radialSegments, 45716 data.heightSegments, 45717 data.openEnded, 45718 data.thetaStart, 45719 data.thetaLength 45720 ); 45721 45722 break; 45723 45724 case 'ConeGeometry': 45725 case 'ConeBufferGeometry': 45726 45727 geometry = new Geometries[ data.type ]( 45728 data.radius, 45729 data.height, 45730 data.radialSegments, 45731 data.heightSegments, 45732 data.openEnded, 45733 data.thetaStart, 45734 data.thetaLength 45735 ); 45736 45737 break; 45738 45739 case 'SphereGeometry': 45740 case 'SphereBufferGeometry': 45741 45742 geometry = new Geometries[ data.type ]( 45743 data.radius, 45744 data.widthSegments, 45745 data.heightSegments, 45746 data.phiStart, 45747 data.phiLength, 45748 data.thetaStart, 45749 data.thetaLength 45750 ); 45751 45752 break; 45753 45754 case 'DodecahedronGeometry': 45755 case 'DodecahedronBufferGeometry': 45756 case 'IcosahedronGeometry': 45757 case 'IcosahedronBufferGeometry': 45758 case 'OctahedronGeometry': 45759 case 'OctahedronBufferGeometry': 45760 case 'TetrahedronGeometry': 45761 case 'TetrahedronBufferGeometry': 45762 45763 geometry = new Geometries[ data.type ]( 45764 data.radius, 45765 data.detail 45766 ); 45767 45768 break; 45769 45770 case 'RingGeometry': 45771 case 'RingBufferGeometry': 45772 45773 geometry = new Geometries[ data.type ]( 45774 data.innerRadius, 45775 data.outerRadius, 45776 data.thetaSegments, 45777 data.phiSegments, 45778 data.thetaStart, 45779 data.thetaLength 45780 ); 45781 45782 break; 45783 45784 case 'TorusGeometry': 45785 case 'TorusBufferGeometry': 45786 45787 geometry = new Geometries[ data.type ]( 45788 data.radius, 45789 data.tube, 45790 data.radialSegments, 45791 data.tubularSegments, 45792 data.arc 45793 ); 45794 45795 break; 45796 45797 case 'TorusKnotGeometry': 45798 case 'TorusKnotBufferGeometry': 45799 45800 geometry = new Geometries[ data.type ]( 45801 data.radius, 45802 data.tube, 45803 data.tubularSegments, 45804 data.radialSegments, 45805 data.p, 45806 data.q 45807 ); 45808 45809 break; 45810 45811 case 'LatheGeometry': 45812 case 'LatheBufferGeometry': 45813 45814 geometry = new Geometries[ data.type ]( 45815 data.points, 45816 data.segments, 45817 data.phiStart, 45818 data.phiLength 45819 ); 45820 45821 break; 45822 45823 case 'PolyhedronGeometry': 45824 case 'PolyhedronBufferGeometry': 45825 45826 geometry = new Geometries[ data.type ]( 45827 data.vertices, 45828 data.indices, 45829 data.radius, 45830 data.details 45831 ); 45832 45833 break; 45834 45835 case 'ShapeGeometry': 45836 case 'ShapeBufferGeometry': 45837 45838 var geometryShapes = []; 45839 45840 for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { 45841 45842 var shape = shapes[ data.shapes[ j ] ]; 45843 45844 geometryShapes.push( shape ); 45845 45846 } 45847 45848 geometry = new Geometries[ data.type ]( 45849 geometryShapes, 45850 data.curveSegments 45851 ); 45852 45853 break; 45854 45855 45856 case 'ExtrudeGeometry': 45857 case 'ExtrudeBufferGeometry': 45858 45859 var geometryShapes = []; 45860 45861 for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { 45862 45863 var shape = shapes[ data.shapes[ j ] ]; 45864 45865 geometryShapes.push( shape ); 45866 45867 } 45868 45869 var extrudePath = data.options.extrudePath; 45870 45871 if ( extrudePath !== undefined ) { 45872 45873 data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath ); 45874 45875 } 45876 45877 geometry = new Geometries[ data.type ]( 45878 geometryShapes, 45879 data.options 45880 ); 45881 45882 break; 45883 45884 case 'BufferGeometry': 45885 45886 geometry = bufferGeometryLoader.parse( data ); 45887 45888 break; 45889 45890 case 'Geometry': 45891 45892 geometry = geometryLoader.parse( data, this.texturePath ).geometry; 45893 45894 break; 45895 45896 default: 45897 45898 console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' ); 45899 45900 continue; 45901 45902 } 45903 45904 geometry.uuid = data.uuid; 45905 45906 if ( data.name !== undefined ) geometry.name = data.name; 45907 if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData; 45908 45909 geometries[ data.uuid ] = geometry; 45910 45911 } 45912 45913 } 45914 45915 return geometries; 45916 45917 }, 45918 45919 parseMaterials: function ( json, textures ) { 45920 45921 var materials = {}; 45922 45923 if ( json !== undefined ) { 45924 45925 var loader = new MaterialLoader(); 45926 loader.setTextures( textures ); 45927 45928 for ( var i = 0, l = json.length; i < l; i ++ ) { 45929 45930 var data = json[ i ]; 45931 45932 if ( data.type === 'MultiMaterial' ) { 45933 45934 // Deprecated 45935 45936 var array = []; 45937 45938 for ( var j = 0; j < data.materials.length; j ++ ) { 45939 45940 array.push( loader.parse( data.materials[ j ] ) ); 45941 45942 } 45943 45944 materials[ data.uuid ] = array; 45945 45946 } else { 45947 45948 materials[ data.uuid ] = loader.parse( data ); 45949 45950 } 45951 45952 } 45953 45954 } 45955 45956 return materials; 45957 45958 }, 45959 45960 parseAnimations: function ( json ) { 45961 45962 var animations = []; 45963 45964 for ( var i = 0; i < json.length; i ++ ) { 45965 45966 var data = json[ i ]; 45967 45968 var clip = AnimationClip.parse( data ); 45969 45970 if ( data.uuid !== undefined ) clip.uuid = data.uuid; 45971 45972 animations.push( clip ); 45973 45974 } 45975 45976 return animations; 45977 45978 }, 45979 45980 parseImages: function ( json, onLoad ) { 45981 45982 var scope = this; 45983 var images = {}; 45984 45985 function loadImage( url ) { 45986 45987 scope.manager.itemStart( url ); 45988 45989 return loader.load( url, function () { 45990 45991 scope.manager.itemEnd( url ); 45992 45993 }, undefined, function () { 45994 45995 scope.manager.itemEnd( url ); 45996 scope.manager.itemError( url ); 45997 45998 } ); 45999 46000 } 46001 46002 if ( json !== undefined && json.length > 0 ) { 46003 46004 var manager = new LoadingManager( onLoad ); 46005 46006 var loader = new ImageLoader( manager ); 46007 loader.setCrossOrigin( this.crossOrigin ); 46008 46009 for ( var i = 0, l = json.length; i < l; i ++ ) { 46010 46011 var image = json[ i ]; 46012 var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; 46013 46014 images[ image.uuid ] = loadImage( path ); 46015 46016 } 46017 46018 } 46019 46020 return images; 46021 46022 }, 46023 46024 parseTextures: function ( json, images ) { 46025 46026 function parseConstant( value, type ) { 46027 46028 if ( typeof value === 'number' ) return value; 46029 46030 console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value ); 46031 46032 return type[ value ]; 46033 46034 } 46035 46036 var textures = {}; 46037 46038 if ( json !== undefined ) { 46039 46040 for ( var i = 0, l = json.length; i < l; i ++ ) { 46041 46042 var data = json[ i ]; 46043 46044 if ( data.image === undefined ) { 46045 46046 console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid ); 46047 46048 } 46049 46050 if ( images[ data.image ] === undefined ) { 46051 46052 console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); 46053 46054 } 46055 46056 var texture = new Texture( images[ data.image ] ); 46057 texture.needsUpdate = true; 46058 46059 texture.uuid = data.uuid; 46060 46061 if ( data.name !== undefined ) texture.name = data.name; 46062 46063 if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); 46064 46065 if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); 46066 if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); 46067 if ( data.center !== undefined ) texture.center.fromArray( data.center ); 46068 if ( data.rotation !== undefined ) texture.rotation = data.rotation; 46069 46070 if ( data.wrap !== undefined ) { 46071 46072 texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); 46073 texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); 46074 46075 } 46076 46077 if ( data.format !== undefined ) texture.format = data.format; 46078 46079 if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); 46080 if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); 46081 if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; 46082 46083 if ( data.flipY !== undefined ) texture.flipY = data.flipY; 46084 46085 textures[ data.uuid ] = texture; 46086 46087 } 46088 46089 } 46090 46091 return textures; 46092 46093 }, 46094 46095 parseObject: function ( data, geometries, materials ) { 46096 46097 var object; 46098 46099 function getGeometry( name ) { 46100 46101 if ( geometries[ name ] === undefined ) { 46102 46103 console.warn( 'THREE.ObjectLoader: Undefined geometry', name ); 46104 46105 } 46106 46107 return geometries[ name ]; 46108 46109 } 46110 46111 function getMaterial( name ) { 46112 46113 if ( name === undefined ) return undefined; 46114 46115 if ( Array.isArray( name ) ) { 46116 46117 var array = []; 46118 46119 for ( var i = 0, l = name.length; i < l; i ++ ) { 46120 46121 var uuid = name[ i ]; 46122 46123 if ( materials[ uuid ] === undefined ) { 46124 46125 console.warn( 'THREE.ObjectLoader: Undefined material', uuid ); 46126 46127 } 46128 46129 array.push( materials[ uuid ] ); 46130 46131 } 46132 46133 return array; 46134 46135 } 46136 46137 if ( materials[ name ] === undefined ) { 46138 46139 console.warn( 'THREE.ObjectLoader: Undefined material', name ); 46140 46141 } 46142 46143 return materials[ name ]; 46144 46145 } 46146 46147 switch ( data.type ) { 46148 46149 case 'Scene': 46150 46151 object = new Scene(); 46152 46153 if ( data.background !== undefined ) { 46154 46155 if ( Number.isInteger( data.background ) ) { 46156 46157 object.background = new Color( data.background ); 46158 46159 } 46160 46161 } 46162 46163 if ( data.fog !== undefined ) { 46164 46165 if ( data.fog.type === 'Fog' ) { 46166 46167 object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far ); 46168 46169 } else if ( data.fog.type === 'FogExp2' ) { 46170 46171 object.fog = new FogExp2( data.fog.color, data.fog.density ); 46172 46173 } 46174 46175 } 46176 46177 break; 46178 46179 case 'PerspectiveCamera': 46180 46181 object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); 46182 46183 if ( data.focus !== undefined ) object.focus = data.focus; 46184 if ( data.zoom !== undefined ) object.zoom = data.zoom; 46185 if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; 46186 if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; 46187 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); 46188 46189 break; 46190 46191 case 'OrthographicCamera': 46192 46193 object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); 46194 46195 if ( data.zoom !== undefined ) object.zoom = data.zoom; 46196 if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); 46197 46198 break; 46199 46200 case 'AmbientLight': 46201 46202 object = new AmbientLight( data.color, data.intensity ); 46203 46204 break; 46205 46206 case 'DirectionalLight': 46207 46208 object = new DirectionalLight( data.color, data.intensity ); 46209 46210 break; 46211 46212 case 'PointLight': 46213 46214 object = new PointLight( data.color, data.intensity, data.distance, data.decay ); 46215 46216 break; 46217 46218 case 'RectAreaLight': 46219 46220 object = new RectAreaLight( data.color, data.intensity, data.width, data.height ); 46221 46222 break; 46223 46224 case 'SpotLight': 46225 46226 object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay ); 46227 46228 break; 46229 46230 case 'HemisphereLight': 46231 46232 object = new HemisphereLight( data.color, data.groundColor, data.intensity ); 46233 46234 break; 46235 46236 case 'SkinnedMesh': 46237 46238 console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' ); 46239 46240 case 'Mesh': 46241 46242 var geometry = getGeometry( data.geometry ); 46243 var material = getMaterial( data.material ); 46244 46245 if ( geometry.bones && geometry.bones.length > 0 ) { 46246 46247 object = new SkinnedMesh( geometry, material ); 46248 46249 } else { 46250 46251 object = new Mesh( geometry, material ); 46252 46253 } 46254 46255 break; 46256 46257 case 'LOD': 46258 46259 object = new LOD(); 46260 46261 break; 46262 46263 case 'Line': 46264 46265 object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); 46266 46267 break; 46268 46269 case 'LineLoop': 46270 46271 object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) ); 46272 46273 break; 46274 46275 case 'LineSegments': 46276 46277 object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) ); 46278 46279 break; 46280 46281 case 'PointCloud': 46282 case 'Points': 46283 46284 object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) ); 46285 46286 break; 46287 46288 case 'Sprite': 46289 46290 object = new Sprite( getMaterial( data.material ) ); 46291 46292 break; 46293 46294 case 'Group': 46295 46296 object = new Group(); 46297 46298 break; 46299 46300 default: 46301 46302 object = new Object3D(); 46303 46304 } 46305 46306 object.uuid = data.uuid; 46307 46308 if ( data.name !== undefined ) object.name = data.name; 46309 46310 if ( data.matrix !== undefined ) { 46311 46312 object.matrix.fromArray( data.matrix ); 46313 46314 if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate; 46315 if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); 46316 46317 } else { 46318 46319 if ( data.position !== undefined ) object.position.fromArray( data.position ); 46320 if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); 46321 if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); 46322 if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); 46323 46324 } 46325 46326 if ( data.castShadow !== undefined ) object.castShadow = data.castShadow; 46327 if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow; 46328 46329 if ( data.shadow ) { 46330 46331 if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; 46332 if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; 46333 if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); 46334 if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); 46335 46336 } 46337 46338 if ( data.visible !== undefined ) object.visible = data.visible; 46339 if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled; 46340 if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder; 46341 if ( data.userData !== undefined ) object.userData = data.userData; 46342 46343 if ( data.children !== undefined ) { 46344 46345 var children = data.children; 46346 46347 for ( var i = 0; i < children.length; i ++ ) { 46348 46349 object.add( this.parseObject( children[ i ], geometries, materials ) ); 46350 46351 } 46352 46353 } 46354 46355 if ( data.type === 'LOD' ) { 46356 46357 var levels = data.levels; 46358 46359 for ( var l = 0; l < levels.length; l ++ ) { 46360 46361 var level = levels[ l ]; 46362 var child = object.getObjectByProperty( 'uuid', level.object ); 46363 46364 if ( child !== undefined ) { 46365 46366 object.addLevel( child, level.distance ); 46367 46368 } 46369 46370 } 46371 46372 } 46373 46374 return object; 46375 46376 } 46377 46378 } ); 46379 46380 var TEXTURE_MAPPING = { 46381 UVMapping: UVMapping, 46382 CubeReflectionMapping: CubeReflectionMapping, 46383 CubeRefractionMapping: CubeRefractionMapping, 46384 EquirectangularReflectionMapping: EquirectangularReflectionMapping, 46385 EquirectangularRefractionMapping: EquirectangularRefractionMapping, 46386 SphericalReflectionMapping: SphericalReflectionMapping, 46387 CubeUVReflectionMapping: CubeUVReflectionMapping, 46388 CubeUVRefractionMapping: CubeUVRefractionMapping 46389 }; 46390 46391 var TEXTURE_WRAPPING = { 46392 RepeatWrapping: RepeatWrapping, 46393 ClampToEdgeWrapping: ClampToEdgeWrapping, 46394 MirroredRepeatWrapping: MirroredRepeatWrapping 46395 }; 46396 46397 var TEXTURE_FILTER = { 46398 NearestFilter: NearestFilter, 46399 NearestMipMapNearestFilter: NearestMipMapNearestFilter, 46400 NearestMipMapLinearFilter: NearestMipMapLinearFilter, 46401 LinearFilter: LinearFilter, 46402 LinearMipMapNearestFilter: LinearMipMapNearestFilter, 46403 LinearMipMapLinearFilter: LinearMipMapLinearFilter 46404 }; 46405 46406 /** 46407 * @author zz85 / http://www.lab4games.net/zz85/blog 46408 * minimal class for proxing functions to Path. Replaces old "extractSubpaths()" 46409 **/ 46410 46411 function ShapePath() { 46412 46413 this.type = 'ShapePath'; 46414 46415 this.color = new Color(); 46416 46417 this.subPaths = []; 46418 this.currentPath = null; 46419 46420 } 46421 46422 Object.assign( ShapePath.prototype, { 46423
46424 moveTo: function ( x, y ) { 46425 46426 this.currentPath = new Path(); 46427 this.subPaths.push( this.currentPath ); 46428 this.currentPath.moveTo( x, y ); 46429 46430 }, 46431 46432 lineTo: function ( x, y ) { 46433 46434 this.currentPath.lineTo( x, y ); 46435 46436 }, 46437 46438 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { 46439 46440 this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); 46441 46442 }, 46443 46444 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { 46445 46446 this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); 46447 46448 }, 46449 46450 splineThru: function ( pts ) { 46451 46452 this.currentPath.splineThru( pts ); 46453 46454 }, 46455 46456 toShapes: function ( isCCW, noHoles ) { 46457 46458 function toShapesNoHoles( inSubpaths ) { 46459 46460 var shapes = []; 46461 46462 for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { 46463 46464 var tmpPath = inSubpaths[ i ]; 46465 46466 var tmpShape = new Shape(); 46467 tmpShape.curves = tmpPath.curves; 46468 46469 shapes.push( tmpShape ); 46470 46471 } 46472 46473 return shapes; 46474 46475 } 46476 46477 function isPointInsidePolygon( inPt, inPolygon ) { 46478 46479 var polyLen = inPolygon.length; 46480 46481 // inPt on polygon contour => immediate success or 46482 // toggling of inside/outside at every single! intersection point of an edge 46483 // with the horizontal line through inPt, left of inPt 46484 // not counting lowerY endpoints of edges and whole edges on that line 46485 var inside = false;
vendor: 4,871 bytes, lines 46486-46700
46486 for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { 46487 46488 var edgeLowPt = inPolygon[ p ]; 46489 var edgeHighPt = inPolygon[ q ]; 46490 46491 var edgeDx = edgeHighPt.x - edgeLowPt.x; 46492 var edgeDy = edgeHighPt.y - edgeLowPt.y; 46493 46494 if ( Math.abs( edgeDy ) > Number.EPSILON ) { 46495 46496 // not parallel 46497 if ( edgeDy < 0 ) { 46498 46499 edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; 46500 edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; 46501 46502 } 46503 if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; 46504 46505 if ( inPt.y === edgeLowPt.y ) { 46506 46507 if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? 46508 // continue; // no intersection or edgeLowPt => doesn't count !!! 46509 46510 } else { 46511 46512 var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); 46513 if ( perpEdge === 0 ) return true; // inPt is on contour ? 46514 if ( perpEdge < 0 ) continue; 46515 inside = ! inside; // true intersection left of inPt 46516 46517 } 46518 46519 } else { 46520 46521 // parallel or collinear 46522 if ( inPt.y !== edgeLowPt.y ) continue; // parallel 46523 // edge lies on the same horizontal line as inPt 46524 if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || 46525 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! 46526 // continue; 46527 46528 } 46529 46530 } 46531 46532 return inside; 46533 46534 } 46535 46536 var isClockWise = ShapeUtils.isClockWise; 46537 46538 var subPaths = this.subPaths; 46539 if ( subPaths.length === 0 ) return []; 46540 46541 if ( noHoles === true ) return toShapesNoHoles( subPaths ); 46542 46543 46544 var solid, tmpPath, tmpShape, shapes = []; 46545 46546 if ( subPaths.length === 1 ) { 46547 46548 tmpPath = subPaths[ 0 ]; 46549 tmpShape = new Shape(); 46550 tmpShape.curves = tmpPath.curves; 46551 shapes.push( tmpShape ); 46552 return shapes; 46553 46554 } 46555 46556 var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); 46557 holesFirst = isCCW ? ! holesFirst : holesFirst; 46558 46559 // console.log("Holes first", holesFirst); 46560 46561 var betterShapeHoles = []; 46562 var newShapes = []; 46563 var newShapeHoles = []; 46564 var mainIdx = 0; 46565 var tmpPoints; 46566 46567 newShapes[ mainIdx ] = undefined; 46568 newShapeHoles[ mainIdx ] = []; 46569 46570 for ( var i = 0, l = subPaths.length; i < l; i ++ ) { 46571 46572 tmpPath = subPaths[ i ]; 46573 tmpPoints = tmpPath.getPoints(); 46574 solid = isClockWise( tmpPoints ); 46575 solid = isCCW ? ! solid : solid; 46576 46577 if ( solid ) { 46578 46579 if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; 46580 46581 newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; 46582 newShapes[ mainIdx ].s.curves = tmpPath.curves; 46583 46584 if ( holesFirst ) mainIdx ++; 46585 newShapeHoles[ mainIdx ] = []; 46586 46587 //console.log('cw', i); 46588 46589 } else { 46590 46591 newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); 46592 46593 //console.log('ccw', i); 46594 46595 } 46596 46597 } 46598 46599 // only Holes? -> probably all Shapes with wrong orientation 46600 if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); 46601 46602 46603 if ( newShapes.length > 1 ) { 46604 46605 var ambiguous = false; 46606 var toChange = []; 46607 46608 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { 46609 46610 betterShapeHoles[ sIdx ] = []; 46611 46612 } 46613 46614 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { 46615 46616 var sho = newShapeHoles[ sIdx ]; 46617 46618 for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { 46619 46620 var ho = sho[ hIdx ]; 46621 var hole_unassigned = true; 46622 46623 for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { 46624 46625 if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { 46626 46627 if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); 46628 if ( hole_unassigned ) { 46629 46630 hole_unassigned = false; 46631 betterShapeHoles[ s2Idx ].push( ho ); 46632 46633 } else { 46634 46635 ambiguous = true; 46636 46637 } 46638 46639 } 46640 46641 } 46642 if ( hole_unassigned ) { 46643 46644 betterShapeHoles[ sIdx ].push( ho ); 46645 46646 } 46647 46648 } 46649 46650 } 46651 // console.log("ambiguous: ", ambiguous); 46652 if ( toChange.length > 0 ) { 46653 46654 // console.log("to change: ", toChange); 46655 if ( ! ambiguous ) newShapeHoles = betterShapeHoles; 46656 46657 } 46658 46659 } 46660 46661 var tmpHoles; 46662 46663 for ( var i = 0, il = newShapes.length; i < il; i ++ ) { 46664 46665 tmpShape = newShapes[ i ].s; 46666 shapes.push( tmpShape ); 46667 tmpHoles = newShapeHoles[ i ]; 46668 46669 for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { 46670 46671 tmpShape.holes.push( tmpHoles[ j ].h ); 46672 46673 } 46674 46675 } 46676 46677 //console.log("shape", shapes); 46678 46679 return shapes; 46680 46681 } 46682 46683 } ); 46684 46685 /** 46686 * @author zz85 / http://www.lab4games.net/zz85/blog 46687 * @author mrdoob / http://mrdoob.com/ 46688 */ 46689 46690 46691 function Font( data ) { 46692 46693 this.type = 'Font'; 46694 46695 this.data = data; 46696 46697 } 46698 46699 Object.assign( Font.prototype, { 46700
46701 isFont: true, 46702 46703 generateShapes: function ( text, size, divisions ) { 46704 46705 if ( size === undefined ) size = 100; 46706 if ( divisions === undefined ) divisions = 4; 46707 46708 var shapes = []; 46709 var paths = createPaths( text, size, divisions, this.data ); 46710 46711 for ( var p = 0, pl = paths.length; p < pl; p ++ ) { 46712 46713 Array.prototype.push.apply( shapes, paths[ p ].toShapes() ); 46714 46715 } 46716 46717 return shapes; 46718 46719 } 46720 46721 } ); 46722 46723 function createPaths( text, size, divisions, data ) { 46724 46725 var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // see #13988 46726 var scale = size / data.resolution; 46727 var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; 46728 46729 var paths = []; 46730 46731 var offsetX = 0, offsetY = 0; 46732 46733 for ( var i = 0; i < chars.length; i ++ ) { 46734 46735 var char = chars[ i ]; 46736 46737 if ( char === '\n' ) { 46738 46739 offsetX = 0; 46740 offsetY -= line_height; 46741 46742 } else { 46743 46744 var ret = createPath( char, divisions, scale, offsetX, offsetY, data ); 46745 offsetX += ret.offsetX; 46746 paths.push( ret.path ); 46747 46748 } 46749 46750 } 46751 46752 return paths; 46753 46754 } 46755 46756 function createPath( char, divisions, scale, offsetX, offsetY, data ) { 46757 46758 var glyph = data.glyphs[ char ] || data.glyphs[ '?' ]; 46759 46760 if ( ! glyph ) return; 46761 46762 var path = new ShapePath(); 46763 46764 var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; 46765 46766 if ( glyph.o ) { 46767 46768 var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); 46769 46770 for ( var i = 0, l = outline.length; i < l; ) { 46771 46772 var action = outline[ i ++ ]; 46773 46774 switch ( action ) { 46775 46776 case 'm': // moveTo 46777 46778 x = outline[ i ++ ] * scale + offsetX; 46779 y = outline[ i ++ ] * scale + offsetY; 46780 46781 path.moveTo( x, y ); 46782 46783 break; 46784 46785 case 'l': // lineTo 46786 46787 x = outline[ i ++ ] * scale + offsetX; 46788 y = outline[ i ++ ] * scale + offsetY; 46789 46790 path.lineTo( x, y ); 46791 46792 break; 46793 46794 case 'q': // quadraticCurveTo 46795 46796 cpx = outline[ i ++ ] * scale + offsetX; 46797 cpy = outline[ i ++ ] * scale + offsetY; 46798 cpx1 = outline[ i ++ ] * scale + offsetX; 46799 cpy1 = outline[ i ++ ] * scale + offsetY; 46800 46801 path.quadraticCurveTo( cpx1, cpy1, cpx, cpy ); 46802 46803 break; 46804 46805 case 'b': // bezierCurveTo 46806 46807 cpx = outline[ i ++ ] * scale + offsetX; 46808 cpy = outline[ i ++ ] * scale + offsetY; 46809 cpx1 = outline[ i ++ ] * scale + offsetX; 46810 cpy1 = outline[ i ++ ] * scale + offsetY; 46811 cpx2 = outline[ i ++ ] * scale + offsetX; 46812 cpy2 = outline[ i ++ ] * scale + offsetY; 46813 46814 path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy ); 46815 46816 break; 46817 46818 } 46819 46820 } 46821 46822 } 46823 46824 return { offsetX: glyph.ha * scale, path: path }; 46825 46826 } 46827 46828 /** 46829 * @author mrdoob / http://mrdoob.com/ 46830 */ 46831 46832 function FontLoader( manager ) { 46833 46834 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 46835 46836 } 46837 46838 Object.assign( FontLoader.prototype, { 46839
46840 load: function ( url, onLoad, onProgress, onError ) { 46841 46842 var scope = this; 46843 46844 var loader = new FileLoader( this.manager ); 46845 loader.setPath( this.path ); 46846 loader.load( url, function ( text ) { 46847 46848 var json; 46849 46850 try { 46851 46852 json = JSON.parse( text ); 46853 46854 } catch ( e ) { 46855 46856 console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' ); 46857 json = JSON.parse( text.substring( 65, text.length - 2 ) ); 46858 46859 } 46860 46861 var font = scope.parse( json ); 46862 46863 if ( onLoad ) onLoad( font ); 46864 46865 }, onProgress, onError ); 46866 46867 }, 46868 46869 parse: function ( json ) { 46870 46871 return new Font( json ); 46872 46873 }, 46874 46875 setPath: function ( value ) { 46876 46877 this.path = value; 46878 return this; 46879 46880 } 46881 46882 } ); 46883 46884 /** 46885 * @author mrdoob / http://mrdoob.com/ 46886 */ 46887 46888 var context; 46889 46890 var AudioContext = { 46891 46892 getContext: function () { 46893 46894 if ( context === undefined ) { 46895 46896 context = new ( window.AudioContext || window.webkitAudioContext )(); 46897 46898 } 46899 46900 return context; 46901 46902 }, 46903 46904 setContext: function ( value ) { 46905 46906 context = value; 46907 46908 } 46909 46910 }; 46911 46912 /** 46913 * @author Reece Aaron Lecrivain / http://reecenotes.com/ 46914 */ 46915 46916 function AudioLoader( manager ) { 46917 46918 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; 46919 46920 } 46921 46922 Object.assign( AudioLoader.prototype, { 46923
46924 load: function ( url, onLoad, onProgress, onError ) { 46925 46926 var loader = new FileLoader( this.manager ); 46927 loader.setResponseType( 'arraybuffer' ); 46928 loader.load( url, function ( buffer ) { 46929 46930 var context = AudioContext.getContext(); 46931 46932 context.decodeAudioData( buffer, function ( audioBuffer ) { 46933 46934 onLoad( audioBuffer ); 46935 46936 } ); 46937 46938 }, onProgress, onError ); 46939 46940 } 46941 46942 } ); 46943 46944 /** 46945 * @author mrdoob / http://mrdoob.com/ 46946 */ 46947 46948 function StereoCamera() { 46949 46950 this.type = 'StereoCamera'; 46951 46952 this.aspect = 1; 46953 46954 this.eyeSep = 0.064; 46955 46956 this.cameraL = new PerspectiveCamera(); 46957 this.cameraL.layers.enable( 1 ); 46958 this.cameraL.matrixAutoUpdate = false; 46959 46960 this.cameraR = new PerspectiveCamera(); 46961 this.cameraR.layers.enable( 2 ); 46962 this.cameraR.matrixAutoUpdate = false; 46963 46964 } 46965 46966 Object.assign( StereoCamera.prototype, { 46967 46968 update: ( function () { 46969 46970 var instance, focus, fov, aspect, near, far, zoom, eyeSep; 46971 46972 var eyeRight = new Matrix4(); 46973 var eyeLeft = new Matrix4(); 46974 46975 return function update( camera ) { 46976 46977 var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov || 46978 aspect !== camera.aspect * this.aspect || near !== camera.near || 46979 far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep; 46980 46981 if ( needsUpdate ) { 46982 46983 instance = this; 46984 focus = camera.focus; 46985 fov = camera.fov; 46986 aspect = camera.aspect * this.aspect; 46987 near = camera.near; 46988 far = camera.far; 46989 zoom = camera.zoom; 46990 46991 // Off-axis stereoscopic effect based on 46992 // http://paulbourke.net/stereographics/stereorender/ 46993 46994 var projectionMatrix = camera.projectionMatrix.clone(); 46995 eyeSep = this.eyeSep / 2; 46996 var eyeSepOnProjection = eyeSep * near / focus; 46997 var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom; 46998 var xmin, xmax; 46999 47000 // translate xOffset 47001 47002 eyeLeft.elements[ 12 ] = - eyeSep; 47003 eyeRight.elements[ 12 ] = eyeSep; 47004 47005 // for left eye 47006 47007 xmin = - ymax * aspect + eyeSepOnProjection; 47008 xmax = ymax * aspect + eyeSepOnProjection; 47009 47010 projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); 47011 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); 47012 47013 this.cameraL.projectionMatrix.copy( projectionMatrix ); 47014 47015 // for right eye 47016 47017 xmin = - ymax * aspect - eyeSepOnProjection; 47018 xmax = ymax * aspect - eyeSepOnProjection; 47019 47020 projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); 47021 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); 47022 47023 this.cameraR.projectionMatrix.copy( projectionMatrix ); 47024 47025 } 47026 47027 this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft ); 47028 this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight ); 47029 47030 }; 47031 47032 } )() 47033 47034 } ); 47035 47036 /** 47037 * Camera for rendering cube maps 47038 * - renders scene into axis-aligned cube 47039 * 47040 * @author alteredq / http://alteredqualia.com/ 47041 */ 47042 47043 function CubeCamera( near, far, cubeResolution ) { 47044 47045 Object3D.call( this ); 47046 47047 this.type = 'CubeCamera'; 47048 47049 var fov = 90, aspect = 1; 47050 47051 var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); 47052 cameraPX.up.set( 0, - 1, 0 ); 47053 cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); 47054 this.add( cameraPX ); 47055 47056 var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); 47057 cameraNX.up.set( 0, - 1, 0 ); 47058 cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); 47059 this.add( cameraNX ); 47060 47061 var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); 47062 cameraPY.up.set( 0, 0, 1 ); 47063 cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); 47064 this.add( cameraPY ); 47065 47066 var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); 47067 cameraNY.up.set( 0, 0, - 1 ); 47068 cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); 47069 this.add( cameraNY ); 47070 47071 var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); 47072 cameraPZ.up.set( 0, - 1, 0 ); 47073 cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); 47074 this.add( cameraPZ ); 47075 47076 var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); 47077 cameraNZ.up.set( 0, - 1, 0 ); 47078 cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); 47079 this.add( cameraNZ ); 47080 47081 var options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; 47082 47083 this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); 47084 this.renderTarget.texture.name = "CubeCamera"; 47085 47086 this.update = function ( renderer, scene ) { 47087 47088 if ( this.parent === null ) this.updateMatrixWorld(); 47089 47090 var renderTarget = this.renderTarget; 47091 var generateMipmaps = renderTarget.texture.generateMipmaps; 47092 47093 renderTarget.texture.generateMipmaps = false;
47094 47095 renderTarget.activeCubeFace = 0; 47096 renderer.render( scene, cameraPX, renderTarget ); 47097 47098 renderTarget.activeCubeFace = 1; 47099 renderer.render( scene, cameraNX, renderTarget ); 47100 47101 renderTarget.activeCubeFace = 2; 47102 renderer.render( scene, cameraPY, renderTarget ); 47103 47104 renderTarget.activeCubeFace = 3; 47105 renderer.render( scene, cameraNY, renderTarget ); 47106 47107 renderTarget.activeCubeFace = 4; 47108 renderer.render( scene, cameraPZ, renderTarget ); 47109 47110 renderTarget.texture.generateMipmaps = generateMipmaps; 47111 47112 renderTarget.activeCubeFace = 5; 47113 renderer.render( scene, cameraNZ, renderTarget ); 47114 47115 renderer.setRenderTarget( null ); 47116 47117 }; 47118 47119 this.clear = function ( renderer, color, depth, stencil ) { 47120 47121 var renderTarget = this.renderTarget; 47122 47123 for ( var i = 0; i < 6; i ++ ) { 47124 47125 renderTarget.activeCubeFace = i; 47126 renderer.setRenderTarget( renderTarget ); 47127 47128 renderer.clear( color, depth, stencil ); 47129 47130 } 47131 47132 renderer.setRenderTarget( null ); 47133 47134 }; 47135 47136 } 47137 47138 CubeCamera.prototype = Object.create( Object3D.prototype ); 47139 CubeCamera.prototype.constructor = CubeCamera; 47140 47141 /** 47142 * @author mrdoob / http://mrdoob.com/ 47143 */ 47144 47145 function AudioListener() { 47146 47147 Object3D.call( this ); 47148 47149 this.type = 'AudioListener'; 47150 47151 this.context = AudioContext.getContext(); 47152 47153 this.gain = this.context.createGain(); 47154 this.gain.connect( this.context.destination ); 47155 47156 this.filter = null; 47157 47158 } 47159 47160 AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), { 47161 47162 constructor: AudioListener, 47163 47164 getInput: function () { 47165 47166 return this.gain; 47167 47168 }, 47169 47170 removeFilter: function ( ) { 47171 47172 if ( this.filter !== null ) { 47173 47174 this.gain.disconnect( this.filter ); 47175 this.filter.disconnect( this.context.destination ); 47176 this.gain.connect( this.context.destination ); 47177 this.filter = null; 47178 47179 } 47180 47181 }, 47182 47183 getFilter: function () { 47184 47185 return this.filter; 47186 47187 }, 47188 47189 setFilter: function ( value ) { 47190 47191 if ( this.filter !== null ) { 47192 47193 this.gain.disconnect( this.filter ); 47194 this.filter.disconnect( this.context.destination ); 47195 47196 } else { 47197 47198 this.gain.disconnect( this.context.destination ); 47199 47200 } 47201 47202 this.filter = value; 47203 this.gain.connect( this.filter ); 47204 this.filter.connect( this.context.destination ); 47205 47206 }, 47207 47208 getMasterVolume: function () { 47209 47210 return this.gain.gain.value; 47211 47212 }, 47213 47214 setMasterVolume: function ( value ) { 47215 47216 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); 47217 47218 }, 47219 47220 updateMatrixWorld: ( function () { 47221 47222 var position = new Vector3(); 47223 var quaternion = new Quaternion(); 47224 var scale = new Vector3(); 47225 47226 var orientation = new Vector3(); 47227 47228 return function updateMatrixWorld( force ) { 47229 47230 Object3D.prototype.updateMatrixWorld.call( this, force ); 47231 47232 var listener = this.context.listener; 47233 var up = this.up; 47234 47235 this.matrixWorld.decompose( position, quaternion, scale ); 47236 47237 orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); 47238 47239 if ( listener.positionX ) { 47240 47241 listener.positionX.setValueAtTime( position.x, this.context.currentTime ); 47242 listener.positionY.setValueAtTime( position.y, this.context.currentTime ); 47243 listener.positionZ.setValueAtTime( position.z, this.context.currentTime ); 47244 listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime ); 47245 listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime ); 47246 listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime ); 47247 listener.upX.setValueAtTime( up.x, this.context.currentTime ); 47248 listener.upY.setValueAtTime( up.y, this.context.currentTime ); 47249 listener.upZ.setValueAtTime( up.z, this.context.currentTime ); 47250 47251 } else { 47252 47253 listener.setPosition( position.x, position.y, position.z ); 47254 listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); 47255 47256 } 47257 47258 }; 47259 47260 } )() 47261 47262 } ); 47263 47264 /** 47265 * @author mrdoob / http://mrdoob.com/ 47266 * @author Reece Aaron Lecrivain / http://reecenotes.com/ 47267 */ 47268 47269 function Audio( listener ) { 47270 47271 Object3D.call( this ); 47272 47273 this.type = 'Audio'; 47274 47275 this.context = listener.context; 47276 47277 this.gain = this.context.createGain(); 47278 this.gain.connect( listener.getInput() ); 47279 47280 this.autoplay = false;
47281 47282 this.buffer = null; 47283 this.loop = false; 47284 this.startTime = 0; 47285 this.offset = 0; 47286 this.playbackRate = 1; 47287 this.isPlaying = false; 47288 this.hasPlaybackControl = true; 47289 this.sourceType = 'empty'; 47290 47291 this.filters = []; 47292 47293 } 47294 47295 Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { 47296 47297 constructor: Audio, 47298 47299 getOutput: function () { 47300 47301 return this.gain; 47302 47303 }, 47304 47305 setNodeSource: function ( audioNode ) { 47306 47307 this.hasPlaybackControl = false; 47308 this.sourceType = 'audioNode'; 47309 this.source = audioNode; 47310 this.connect(); 47311 47312 return this; 47313 47314 }, 47315 47316 setMediaElementSource: function ( mediaElement ) { 47317 47318 this.hasPlaybackControl = false; 47319 this.sourceType = 'mediaNode'; 47320 this.source = this.context.createMediaElementSource( mediaElement ); 47321 this.connect(); 47322 47323 return this; 47324 47325 }, 47326 47327 setBuffer: function ( audioBuffer ) { 47328 47329 this.buffer = audioBuffer; 47330 this.sourceType = 'buffer'; 47331 47332 if ( this.autoplay ) this.play(); 47333 47334 return this; 47335 47336 }, 47337 47338 play: function () { 47339 47340 if ( this.isPlaying === true ) { 47341 47342 console.warn( 'THREE.Audio: Audio is already playing.' ); 47343 return; 47344 47345 } 47346 47347 if ( this.hasPlaybackControl === false ) { 47348 47349 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47350 return; 47351 47352 } 47353 47354 var source = this.context.createBufferSource(); 47355 47356 source.buffer = this.buffer; 47357 source.loop = this.loop; 47358 source.onended = this.onEnded.bind( this ); 47359 source.playbackRate.setValueAtTime( this.playbackRate, this.startTime ); 47360 this.startTime = this.context.currentTime; 47361 source.start( this.startTime, this.offset ); 47362 47363 this.isPlaying = true; 47364 47365 this.source = source; 47366 47367 return this.connect(); 47368 47369 }, 47370 47371 pause: function () { 47372 47373 if ( this.hasPlaybackControl === false ) { 47374 47375 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47376 return; 47377 47378 } 47379 47380 if ( this.isPlaying === true ) { 47381 47382 this.source.stop(); 47383 this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate; 47384 this.isPlaying = false; 47385 47386 } 47387 47388 return this; 47389 47390 }, 47391 47392 stop: function () { 47393 47394 if ( this.hasPlaybackControl === false ) { 47395 47396 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47397 return; 47398 47399 } 47400 47401 this.source.stop(); 47402 this.offset = 0; 47403 this.isPlaying = false; 47404 47405 return this; 47406 47407 }, 47408 47409 connect: function () { 47410 47411 if ( this.filters.length > 0 ) { 47412 47413 this.source.connect( this.filters[ 0 ] ); 47414 47415 for ( var i = 1, l = this.filters.length; i < l; i ++ ) { 47416 47417 this.filters[ i - 1 ].connect( this.filters[ i ] ); 47418 47419 } 47420 47421 this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); 47422 47423 } else { 47424 47425 this.source.connect( this.getOutput() ); 47426 47427 } 47428 47429 return this; 47430 47431 }, 47432 47433 disconnect: function () { 47434 47435 if ( this.filters.length > 0 ) { 47436 47437 this.source.disconnect( this.filters[ 0 ] ); 47438 47439 for ( var i = 1, l = this.filters.length; i < l; i ++ ) { 47440 47441 this.filters[ i - 1 ].disconnect( this.filters[ i ] ); 47442 47443 } 47444 47445 this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); 47446 47447 } else { 47448 47449 this.source.disconnect( this.getOutput() ); 47450 47451 } 47452 47453 return this; 47454 47455 }, 47456 47457 getFilters: function () { 47458 47459 return this.filters; 47460 47461 }, 47462 47463 setFilters: function ( value ) { 47464 47465 if ( ! value ) value = []; 47466 47467 if ( this.isPlaying === true ) { 47468 47469 this.disconnect(); 47470 this.filters = value; 47471 this.connect(); 47472 47473 } else { 47474 47475 this.filters = value; 47476 47477 } 47478 47479 return this; 47480 47481 }, 47482 47483 getFilter: function () { 47484 47485 return this.getFilters()[ 0 ]; 47486 47487 }, 47488 47489 setFilter: function ( filter ) { 47490 47491 return this.setFilters( filter ? [ filter ] : [] ); 47492 47493 }, 47494 47495 setPlaybackRate: function ( value ) { 47496 47497 if ( this.hasPlaybackControl === false ) { 47498 47499 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47500 return; 47501 47502 } 47503 47504 this.playbackRate = value; 47505 47506 if ( this.isPlaying === true ) { 47507 47508 this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime ); 47509 47510 } 47511 47512 return this; 47513 47514 }, 47515
47516 getPlaybackRate: function () { 47517 47518 return this.playbackRate; 47519 47520 }, 47521 47522 onEnded: function () { 47523 47524 this.isPlaying = false; 47525 47526 }, 47527 47528 getLoop: function () { 47529 47530 if ( this.hasPlaybackControl === false ) { 47531 47532 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47533 return false; 47534 47535 } 47536 47537 return this.loop; 47538 47539 }, 47540 47541 setLoop: function ( value ) { 47542 47543 if ( this.hasPlaybackControl === false ) { 47544 47545 console.warn( 'THREE.Audio: this Audio has no playback control.' ); 47546 return; 47547 47548 } 47549 47550 this.loop = value; 47551 47552 if ( this.isPlaying === true ) { 47553 47554 this.source.loop = this.loop; 47555 47556 } 47557 47558 return this; 47559 47560 }, 47561 47562 getVolume: function () { 47563 47564 return this.gain.gain.value; 47565 47566 }, 47567 47568 setVolume: function ( value ) { 47569 47570 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); 47571 47572 return this; 47573 47574 } 47575 47576 } ); 47577 47578 /** 47579 * @author mrdoob / http://mrdoob.com/ 47580 */ 47581 47582 function PositionalAudio( listener ) { 47583 47584 Audio.call( this, listener ); 47585 47586 this.panner = this.context.createPanner(); 47587 this.panner.connect( this.gain ); 47588 47589 } 47590 47591 PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), { 47592 47593 constructor: PositionalAudio, 47594 47595 getOutput: function () { 47596 47597 return this.panner; 47598 47599 }, 47600 47601 getRefDistance: function () { 47602 47603 return this.panner.refDistance; 47604 47605 }, 47606 47607 setRefDistance: function ( value ) { 47608 47609 this.panner.refDistance = value; 47610 47611 }, 47612 47613 getRolloffFactor: function () { 47614 47615 return this.panner.rolloffFactor; 47616 47617 }, 47618 47619 setRolloffFactor: function ( value ) { 47620 47621 this.panner.rolloffFactor = value; 47622 47623 }, 47624 47625 getDistanceModel: function () { 47626 47627 return this.panner.distanceModel; 47628 47629 }, 47630 47631 setDistanceModel: function ( value ) { 47632 47633 this.panner.distanceModel = value; 47634 47635 }, 47636 47637 getMaxDistance: function () { 47638 47639 return this.panner.maxDistance; 47640 47641 }, 47642 47643 setMaxDistance: function ( value ) { 47644 47645 this.panner.maxDistance = value; 47646 47647 }, 47648 47649 updateMatrixWorld: ( function () { 47650 47651 var position = new Vector3(); 47652 47653 return function updateMatrixWorld( force ) { 47654 47655 Object3D.prototype.updateMatrixWorld.call( this, force ); 47656 47657 position.setFromMatrixPosition( this.matrixWorld ); 47658 47659 this.panner.setPosition( position.x, position.y, position.z ); 47660 47661 }; 47662 47663 } )() 47664 47665 47666 } ); 47667 47668 /** 47669 * @author mrdoob / http://mrdoob.com/ 47670 */ 47671 47672 function AudioAnalyser( audio, fftSize ) { 47673 47674 this.analyser = audio.context.createAnalyser(); 47675 this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048; 47676 47677 this.data = new Uint8Array( this.analyser.frequencyBinCount ); 47678 47679 audio.getOutput().connect( this.analyser ); 47680 47681 } 47682 47683 Object.assign( AudioAnalyser.prototype, { 47684
vendor: 37,856 bytes, lines 47685-49303
47685 getFrequencyData: function () { 47686 47687 this.analyser.getByteFrequencyData( this.data ); 47688 47689 return this.data; 47690 47691 }, 47692 47693 getAverageFrequency: function () { 47694 47695 var value = 0, data = this.getFrequencyData(); 47696 47697 for ( var i = 0; i < data.length; i ++ ) { 47698 47699 value += data[ i ]; 47700 47701 } 47702 47703 return value / data.length; 47704 47705 } 47706 47707 } ); 47708 47709 /** 47710 * 47711 * Buffered scene graph property that allows weighted accumulation. 47712 * 47713 * 47714 * @author Ben Houston / http://clara.io/ 47715 * @author David Sarno / http://lighthaus.us/ 47716 * @author tschw 47717 */ 47718 47719 function PropertyMixer( binding, typeName, valueSize ) { 47720 47721 this.binding = binding; 47722 this.valueSize = valueSize; 47723 47724 var bufferType = Float64Array, 47725 mixFunction; 47726 47727 switch ( typeName ) { 47728 47729 case 'quaternion': 47730 mixFunction = this._slerp; 47731 break; 47732 47733 case 'string': 47734 case 'bool': 47735 bufferType = Array; 47736 mixFunction = this._select; 47737 break; 47738 47739 default: 47740 mixFunction = this._lerp; 47741 47742 } 47743 47744 this.buffer = new bufferType( valueSize * 4 ); 47745 // layout: [ incoming | accu0 | accu1 | orig ] 47746 // 47747 // interpolators can use .buffer as their .result 47748 // the data then goes to 'incoming' 47749 // 47750 // 'accu0' and 'accu1' are used frame-interleaved for 47751 // the cumulative result and are compared to detect 47752 // changes 47753 // 47754 // 'orig' stores the original state of the property 47755 47756 this._mixBufferRegion = mixFunction; 47757 47758 this.cumulativeWeight = 0; 47759 47760 this.useCount = 0; 47761 this.referenceCount = 0; 47762 47763 } 47764 47765 Object.assign( PropertyMixer.prototype, { 47766 47767 // accumulate data in the 'incoming' region into 'accu<i>' 47768 accumulate: function ( accuIndex, weight ) { 47769 47770 // note: happily accumulating nothing when weight = 0, the caller knows 47771 // the weight and shouldn't have made the call in the first place 47772 47773 var buffer = this.buffer, 47774 stride = this.valueSize, 47775 offset = accuIndex * stride + stride, 47776 47777 currentWeight = this.cumulativeWeight; 47778 47779 if ( currentWeight === 0 ) { 47780 47781 // accuN := incoming * weight 47782 47783 for ( var i = 0; i !== stride; ++ i ) { 47784 47785 buffer[ offset + i ] = buffer[ i ]; 47786 47787 } 47788 47789 currentWeight = weight; 47790 47791 } else { 47792 47793 // accuN := accuN + incoming * weight 47794 47795 currentWeight += weight; 47796 var mix = weight / currentWeight; 47797 this._mixBufferRegion( buffer, offset, 0, mix, stride ); 47798 47799 } 47800 47801 this.cumulativeWeight = currentWeight; 47802 47803 }, 47804 47805 // apply the state of 'accu<i>' to the binding when accus differ 47806 apply: function ( accuIndex ) { 47807 47808 var stride = this.valueSize, 47809 buffer = this.buffer, 47810 offset = accuIndex * stride + stride, 47811 47812 weight = this.cumulativeWeight, 47813 47814 binding = this.binding; 47815 47816 this.cumulativeWeight = 0; 47817 47818 if ( weight < 1 ) { 47819 47820 // accuN := accuN + original * ( 1 - cumulativeWeight ) 47821 47822 var originalValueOffset = stride * 3; 47823 47824 this._mixBufferRegion( 47825 buffer, offset, originalValueOffset, 1 - weight, stride ); 47826 47827 } 47828 47829 for ( var i = stride, e = stride + stride; i !== e; ++ i ) { 47830 47831 if ( buffer[ i ] !== buffer[ i + stride ] ) { 47832 47833 // value has changed -> update scene graph 47834 47835 binding.setValue( buffer, offset ); 47836 break; 47837 47838 } 47839 47840 } 47841 47842 }, 47843 47844 // remember the state of the bound property and copy it to both accus 47845 saveOriginalState: function () { 47846 47847 var binding = this.binding; 47848 47849 var buffer = this.buffer, 47850 stride = this.valueSize, 47851 47852 originalValueOffset = stride * 3; 47853 47854 binding.getValue( buffer, originalValueOffset ); 47855 47856 // accu[0..1] := orig -- initially detect changes against the original 47857 for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) { 47858 47859 buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; 47860 47861 } 47862 47863 this.cumulativeWeight = 0; 47864 47865 }, 47866 47867 // apply the state previously taken via 'saveOriginalState' to the binding 47868 restoreOriginalState: function () { 47869 47870 var originalValueOffset = this.valueSize * 3; 47871 this.binding.setValue( this.buffer, originalValueOffset ); 47872 47873 }, 47874 47875 47876 // mix functions 47877 47878 _select: function ( buffer, dstOffset, srcOffset, t, stride ) { 47879 47880 if ( t >= 0.5 ) { 47881 47882 for ( var i = 0; i !== stride; ++ i ) { 47883 47884 buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; 47885 47886 } 47887 47888 } 47889 47890 }, 47891 47892 _slerp: function ( buffer, dstOffset, srcOffset, t ) { 47893 47894 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t ); 47895 47896 }, 47897 47898 _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) { 47899 47900 var s = 1 - t; 47901 47902 for ( var i = 0; i !== stride; ++ i ) { 47903 47904 var j = dstOffset + i; 47905 47906 buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t; 47907 47908 } 47909 47910 } 47911 47912 } ); 47913 47914 /** 47915 * 47916 * A reference to a real property in the scene graph. 47917 * 47918 * 47919 * @author Ben Houston / http://clara.io/ 47920 * @author David Sarno / http://lighthaus.us/ 47921 * @author tschw 47922 */ 47923 47924 // Characters [].:/ are reserved for track binding syntax. 47925 var RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; 47926 47927 function Composite( targetGroup, path, optionalParsedPath ) { 47928 47929 var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path ); 47930 47931 this._targetGroup = targetGroup; 47932 this._bindings = targetGroup.subscribe_( path, parsedPath ); 47933 47934 } 47935 47936 Object.assign( Composite.prototype, { 47937 47938 getValue: function ( array, offset ) { 47939 47940 this.bind(); // bind all binding 47941 47942 var firstValidIndex = this._targetGroup.nCachedObjects_, 47943 binding = this._bindings[ firstValidIndex ]; 47944 47945 // and only call .getValue on the first 47946 if ( binding !== undefined ) binding.getValue( array, offset ); 47947 47948 }, 47949 47950 setValue: function ( array, offset ) { 47951 47952 var bindings = this._bindings; 47953 47954 for ( var i = this._targetGroup.nCachedObjects_, 47955 n = bindings.length; i !== n; ++ i ) { 47956 47957 bindings[ i ].setValue( array, offset ); 47958 47959 } 47960 47961 }, 47962 47963 bind: function () { 47964 47965 var bindings = this._bindings; 47966 47967 for ( var i = this._targetGroup.nCachedObjects_, 47968 n = bindings.length; i !== n; ++ i ) { 47969 47970 bindings[ i ].bind(); 47971 47972 } 47973 47974 }, 47975 47976 unbind: function () { 47977 47978 var bindings = this._bindings; 47979 47980 for ( var i = this._targetGroup.nCachedObjects_, 47981 n = bindings.length; i !== n; ++ i ) { 47982 47983 bindings[ i ].unbind(); 47984 47985 } 47986 47987 } 47988 47989 } ); 47990 47991 47992 function PropertyBinding( rootNode, path, parsedPath ) { 47993 47994 this.path = path; 47995 this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path ); 47996 47997 this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode; 47998 47999 this.rootNode = rootNode; 48000 48001 } 48002 48003 Object.assign( PropertyBinding, { 48004 48005 Composite: Composite, 48006 48007 create: function ( root, path, parsedPath ) { 48008 48009 if ( ! ( root && root.isAnimationObjectGroup ) ) { 48010 48011 return new PropertyBinding( root, path, parsedPath ); 48012 48013 } else { 48014 48015 return new PropertyBinding.Composite( root, path, parsedPath ); 48016 48017 } 48018 48019 }, 48020 48021 /** 48022 * Replaces spaces with underscores and removes unsupported characters from 48023 * node names, to ensure compatibility with parseTrackName(). 48024 * 48025 * @param {string} name Node name to be sanitized. 48026 * @return {string} 48027 */ 48028 sanitizeNodeName: ( function () { 48029 48030 var reservedRe = new RegExp( '[' + RESERVED_CHARS_RE + ']', 'g' ); 48031 48032 return function sanitizeNodeName( name ) { 48033 48034 return name.replace( /\s/g, '_' ).replace( reservedRe, '' ); 48035 48036 }; 48037 48038 }() ), 48039 48040 parseTrackName: function () { 48041 48042 // Attempts to allow node names from any language. ES5's `\w` regexp matches 48043 // only latin characters, and the unicode \p{L} is not yet supported. So 48044 // instead, we exclude reserved characters and match everything else. 48045 var wordChar = '[^' + RESERVED_CHARS_RE + ']'; 48046 var wordCharOrDot = '[^' + RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; 48047 48048 // Parent directories, delimited by '/' or ':'. Currently unused, but must 48049 // be matched to parse the rest of the track name. 48050 var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar ); 48051 48052 // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. 48053 var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot ); 48054 48055 // Object on target node, and accessor. May not contain reserved 48056 // characters. Accessor may contain any character except closing bracket. 48057 var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar ); 48058 48059 // Property and accessor. May not contain reserved characters. Accessor may 48060 // contain any non-bracket characters. 48061 var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar ); 48062 48063 var trackRe = new RegExp( '' 48064 + '^' 48065 + directoryRe 48066 + nodeRe 48067 + objectRe 48068 + propertyRe 48069 + '$' 48070 ); 48071 48072 var supportedObjectNames = [ 'material', 'materials', 'bones' ]; 48073 48074 return function parseTrackName( trackName ) { 48075 48076 var matches = trackRe.exec( trackName ); 48077 48078 if ( ! matches ) { 48079 48080 throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); 48081 48082 } 48083 48084 var results = { 48085 // directoryName: matches[ 1 ], // (tschw) currently unused 48086 nodeName: matches[ 2 ], 48087 objectName: matches[ 3 ], 48088 objectIndex: matches[ 4 ], 48089 propertyName: matches[ 5 ], // required 48090 propertyIndex: matches[ 6 ] 48091 }; 48092 48093 var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); 48094 48095 if ( lastDot !== undefined && lastDot !== - 1 ) { 48096 48097 var objectName = results.nodeName.substring( lastDot + 1 ); 48098 48099 // Object names must be checked against a whitelist. Otherwise, there 48100 // is no way to parse 'foo.bar.baz': 'baz' must be a property, but 48101 // 'bar' could be the objectName, or part of a nodeName (which can 48102 // include '.' characters). 48103 if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) { 48104 48105 results.nodeName = results.nodeName.substring( 0, lastDot ); 48106 results.objectName = objectName; 48107 48108 } 48109 48110 } 48111 48112 if ( results.propertyName === null || results.propertyName.length === 0 ) { 48113 48114 throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); 48115 48116 } 48117 48118 return results; 48119 48120 }; 48121 48122 }(), 48123 48124 findNode: function ( root, nodeName ) { 48125 48126 if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { 48127 48128 return root; 48129 48130 } 48131 48132 // search into skeleton bones. 48133 if ( root.skeleton ) { 48134 48135 var bone = root.skeleton.getBoneByName( nodeName ); 48136 48137 if ( bone !== undefined ) { 48138 48139 return bone; 48140 48141 } 48142 48143 } 48144 48145 // search into node subtree. 48146 if ( root.children ) { 48147 48148 var searchNodeSubtree = function ( children ) { 48149 48150 for ( var i = 0; i < children.length; i ++ ) { 48151 48152 var childNode = children[ i ]; 48153 48154 if ( childNode.name === nodeName || childNode.uuid === nodeName ) { 48155 48156 return childNode; 48157 48158 } 48159 48160 var result = searchNodeSubtree( childNode.children ); 48161 48162 if ( result ) return result; 48163 48164 } 48165 48166 return null; 48167 48168 }; 48169 48170 var subTreeNode = searchNodeSubtree( root.children ); 48171 48172 if ( subTreeNode ) { 48173 48174 return subTreeNode; 48175 48176 } 48177 48178 } 48179 48180 return null; 48181 48182 } 48183 48184 } ); 48185 48186 Object.assign( PropertyBinding.prototype, { // prototype, continued 48187 48188 // these are used to "bind" a nonexistent property 48189 _getValue_unavailable: function () {}, 48190 _setValue_unavailable: function () {}, 48191 48192 BindingType: { 48193 Direct: 0, 48194 EntireArray: 1, 48195 ArrayElement: 2, 48196 HasFromToArray: 3 48197 }, 48198 48199 Versioning: { 48200 None: 0, 48201 NeedsUpdate: 1, 48202 MatrixWorldNeedsUpdate: 2 48203 }, 48204 48205 GetterByBindingType: [ 48206 48207 function getValue_direct( buffer, offset ) { 48208 48209 buffer[ offset ] = this.node[ this.propertyName ]; 48210 48211 }, 48212 48213 function getValue_array( buffer, offset ) { 48214 48215 var source = this.resolvedProperty; 48216 48217 for ( var i = 0, n = source.length; i !== n; ++ i ) { 48218 48219 buffer[ offset ++ ] = source[ i ]; 48220 48221 } 48222 48223 }, 48224 48225 function getValue_arrayElement( buffer, offset ) { 48226 48227 buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ]; 48228 48229 }, 48230 48231 function getValue_toArray( buffer, offset ) { 48232 48233 this.resolvedProperty.toArray( buffer, offset ); 48234 48235 } 48236 48237 ], 48238 48239 SetterByBindingTypeAndVersioning: [ 48240 48241 [ 48242 // Direct 48243 48244 function setValue_direct( buffer, offset ) { 48245 48246 this.targetObject[ this.propertyName ] = buffer[ offset ]; 48247 48248 }, 48249 48250 function setValue_direct_setNeedsUpdate( buffer, offset ) { 48251 48252 this.targetObject[ this.propertyName ] = buffer[ offset ]; 48253 this.targetObject.needsUpdate = true; 48254 48255 }, 48256 48257 function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) { 48258 48259 this.targetObject[ this.propertyName ] = buffer[ offset ]; 48260 this.targetObject.matrixWorldNeedsUpdate = true; 48261 48262 } 48263 48264 ], [ 48265 48266 // EntireArray 48267 48268 function setValue_array( buffer, offset ) { 48269 48270 var dest = this.resolvedProperty; 48271 48272 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 48273 48274 dest[ i ] = buffer[ offset ++ ]; 48275 48276 } 48277 48278 }, 48279 48280 function setValue_array_setNeedsUpdate( buffer, offset ) { 48281 48282 var dest = this.resolvedProperty; 48283 48284 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 48285 48286 dest[ i ] = buffer[ offset ++ ]; 48287 48288 } 48289 48290 this.targetObject.needsUpdate = true; 48291 48292 }, 48293 48294 function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) { 48295 48296 var dest = this.resolvedProperty; 48297 48298 for ( var i = 0, n = dest.length; i !== n; ++ i ) { 48299 48300 dest[ i ] = buffer[ offset ++ ]; 48301 48302 } 48303 48304 this.targetObject.matrixWorldNeedsUpdate = true; 48305 48306 } 48307 48308 ], [ 48309 48310 // ArrayElement 48311 48312 function setValue_arrayElement( buffer, offset ) { 48313 48314 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 48315 48316 }, 48317 48318 function setValue_arrayElement_setNeedsUpdate( buffer, offset ) { 48319 48320 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 48321 this.targetObject.needsUpdate = true; 48322 48323 }, 48324 48325 function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) { 48326 48327 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; 48328 this.targetObject.matrixWorldNeedsUpdate = true; 48329 48330 } 48331 48332 ], [ 48333 48334 // HasToFromArray 48335 48336 function setValue_fromArray( buffer, offset ) { 48337 48338 this.resolvedProperty.fromArray( buffer, offset ); 48339 48340 }, 48341 48342 function setValue_fromArray_setNeedsUpdate( buffer, offset ) { 48343 48344 this.resolvedProperty.fromArray( buffer, offset ); 48345 this.targetObject.needsUpdate = true; 48346 48347 }, 48348 48349 function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) { 48350 48351 this.resolvedProperty.fromArray( buffer, offset ); 48352 this.targetObject.matrixWorldNeedsUpdate = true; 48353 48354 } 48355 48356 ] 48357 48358 ], 48359 48360 getValue: function getValue_unbound( targetArray, offset ) { 48361 48362 this.bind(); 48363 this.getValue( targetArray, offset ); 48364 48365 // Note: This class uses a State pattern on a per-method basis: 48366 // 'bind' sets 'this.getValue' / 'setValue' and shadows the 48367 // prototype version of these methods with one that represents 48368 // the bound state. When the property is not found, the methods 48369 // become no-ops. 48370 48371 }, 48372 48373 setValue: function getValue_unbound( sourceArray, offset ) { 48374 48375 this.bind(); 48376 this.setValue( sourceArray, offset ); 48377 48378 }, 48379 48380 // create getter / setter pair for a property in the scene graph 48381 bind: function () { 48382 48383 var targetObject = this.node, 48384 parsedPath = this.parsedPath, 48385 48386 objectName = parsedPath.objectName, 48387 propertyName = parsedPath.propertyName, 48388 propertyIndex = parsedPath.propertyIndex; 48389 48390 if ( ! targetObject ) { 48391 48392 targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode; 48393 48394 this.node = targetObject; 48395 48396 } 48397 48398 // set fail state so we can just 'return' on error 48399 this.getValue = this._getValue_unavailable; 48400 this.setValue = this._setValue_unavailable; 48401 48402 // ensure there is a value node 48403 if ( ! targetObject ) { 48404 48405 console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' ); 48406 return; 48407 48408 } 48409 48410 if ( objectName ) { 48411 48412 var objectIndex = parsedPath.objectIndex; 48413 48414 // special cases were we need to reach deeper into the hierarchy to get the face materials.... 48415 switch ( objectName ) { 48416 48417 case 'materials': 48418 48419 if ( ! targetObject.material ) { 48420 48421 console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); 48422 return; 48423 48424 } 48425 48426 if ( ! targetObject.material.materials ) { 48427 48428 console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this ); 48429 return; 48430 48431 } 48432 48433 targetObject = targetObject.material.materials; 48434 48435 break; 48436 48437 case 'bones': 48438 48439 if ( ! targetObject.skeleton ) { 48440 48441 console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this ); 48442 return; 48443 48444 } 48445 48446 // potential future optimization: skip this if propertyIndex is already an integer 48447 // and convert the integer string to a true integer. 48448 48449 targetObject = targetObject.skeleton.bones; 48450 48451 // support resolving morphTarget names into indices. 48452 for ( var i = 0; i < targetObject.length; i ++ ) { 48453 48454 if ( targetObject[ i ].name === objectIndex ) { 48455 48456 objectIndex = i; 48457 break; 48458 48459 } 48460 48461 } 48462 48463 break; 48464 48465 default: 48466 48467 if ( targetObject[ objectName ] === undefined ) { 48468 48469 console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this ); 48470 return; 48471 48472 } 48473 48474 targetObject = targetObject[ objectName ]; 48475 48476 } 48477 48478 48479 if ( objectIndex !== undefined ) { 48480 48481 if ( targetObject[ objectIndex ] === undefined ) { 48482 48483 console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject ); 48484 return; 48485 48486 } 48487 48488 targetObject = targetObject[ objectIndex ]; 48489 48490 } 48491 48492 } 48493 48494 // resolve property 48495 var nodeProperty = targetObject[ propertyName ]; 48496 48497 if ( nodeProperty === undefined ) { 48498 48499 var nodeName = parsedPath.nodeName; 48500 48501 console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName + 48502 '.' + propertyName + ' but it wasn\'t found.', targetObject ); 48503 return; 48504 48505 } 48506 48507 // determine versioning scheme 48508 var versioning = this.Versioning.None; 48509 48510 if ( targetObject.needsUpdate !== undefined ) { // material 48511 48512 versioning = this.Versioning.NeedsUpdate; 48513 this.targetObject = targetObject; 48514 48515 } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform 48516 48517 versioning = this.Versioning.MatrixWorldNeedsUpdate; 48518 this.targetObject = targetObject; 48519 48520 } 48521 48522 // determine how the property gets bound 48523 var bindingType = this.BindingType.Direct; 48524 48525 if ( propertyIndex !== undefined ) { 48526 48527 // access a sub element of the property array (only primitives are supported right now) 48528 48529 if ( propertyName === "morphTargetInfluences" ) { 48530 48531 // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. 48532 48533 // support resolving morphTarget names into indices. 48534 if ( ! targetObject.geometry ) { 48535 48536 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this ); 48537 return; 48538 48539 } 48540 48541 if ( targetObject.geometry.isBufferGeometry ) { 48542 48543 if ( ! targetObject.geometry.morphAttributes ) { 48544 48545 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this ); 48546 return; 48547 48548 } 48549 48550 for ( var i = 0; i < this.node.geometry.morphAttributes.position.length; i ++ ) { 48551 48552 if ( targetObject.geometry.morphAttributes.position[ i ].name === propertyIndex ) { 48553 48554 propertyIndex = i; 48555 break; 48556 48557 } 48558 48559 } 48560 48561 48562 } else { 48563 48564 if ( ! targetObject.geometry.morphTargets ) { 48565 48566 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.', this ); 48567 return; 48568 48569 } 48570 48571 for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) { 48572 48573 if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) { 48574 48575 propertyIndex = i; 48576 break; 48577 48578 } 48579 48580 } 48581 48582 } 48583 48584 } 48585 48586 bindingType = this.BindingType.ArrayElement; 48587 48588 this.resolvedProperty = nodeProperty; 48589 this.propertyIndex = propertyIndex; 48590 48591 } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) { 48592 48593 // must use copy for Object3D.Euler/Quaternion 48594 48595 bindingType = this.BindingType.HasFromToArray; 48596 48597 this.resolvedProperty = nodeProperty; 48598 48599 } else if ( Array.isArray( nodeProperty ) ) { 48600 48601 bindingType = this.BindingType.EntireArray; 48602 48603 this.resolvedProperty = nodeProperty; 48604 48605 } else { 48606 48607 this.propertyName = propertyName; 48608 48609 } 48610 48611 // select getter / setter 48612 this.getValue = this.GetterByBindingType[ bindingType ]; 48613 this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ]; 48614 48615 }, 48616 48617 unbind: function () { 48618 48619 this.node = null; 48620 48621 // back to the prototype version of getValue / setValue 48622 // note: avoiding to mutate the shape of 'this' via 'delete' 48623 this.getValue = this._getValue_unbound; 48624 this.setValue = this._setValue_unbound; 48625 48626 } 48627 48628 } ); 48629 48630 //!\ DECLARE ALIAS AFTER assign prototype ! 48631 Object.assign( PropertyBinding.prototype, { 48632 48633 // initial state of these methods that calls 'bind' 48634 _getValue_unbound: PropertyBinding.prototype.getValue, 48635 _setValue_unbound: PropertyBinding.prototype.setValue, 48636 48637 } ); 48638 48639 /** 48640 * 48641 * A group of objects that receives a shared animation state. 48642 * 48643 * Usage: 48644 * 48645 * - Add objects you would otherwise pass as 'root' to the 48646 * constructor or the .clipAction method of AnimationMixer. 48647 * 48648 * - Instead pass this object as 'root'. 48649 * 48650 * - You can also add and remove objects later when the mixer 48651 * is running. 48652 * 48653 * Note: 48654 * 48655 * Objects of this class appear as one object to the mixer, 48656 * so cache control of the individual objects must be done 48657 * on the group. 48658 * 48659 * Limitation: 48660 * 48661 * - The animated properties must be compatible among the 48662 * all objects in the group. 48663 * 48664 * - A single property can either be controlled through a 48665 * target group or directly, but not both. 48666 * 48667 * @author tschw 48668 */ 48669 48670 function AnimationObjectGroup() { 48671 48672 this.uuid = _Math.generateUUID(); 48673 48674 // cached objects followed by the active ones 48675 this._objects = Array.prototype.slice.call( arguments ); 48676 48677 this.nCachedObjects_ = 0; // threshold 48678 // note: read by PropertyBinding.Composite 48679 48680 var indices = {}; 48681 this._indicesByUUID = indices; // for bookkeeping 48682 48683 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 48684 48685 indices[ arguments[ i ].uuid ] = i; 48686 48687 } 48688 48689 this._paths = []; // inside: string 48690 this._parsedPaths = []; // inside: { we don't care, here } 48691 this._bindings = []; // inside: Array< PropertyBinding > 48692 this._bindingsIndicesByPath = {}; // inside: indices in these arrays 48693 48694 var scope = this; 48695 48696 this.stats = { 48697 48698 objects: { 48699 get total() { 48700 48701 return scope._objects.length; 48702 48703 }, 48704 get inUse() { 48705 48706 return this.total - scope.nCachedObjects_; 48707 48708 } 48709 }, 48710 get bindingsPerObject() { 48711 48712 return scope._bindings.length; 48713 48714 } 48715 48716 }; 48717 48718 } 48719 48720 Object.assign( AnimationObjectGroup.prototype, { 48721 48722 isAnimationObjectGroup: true, 48723 48724 add: function () { 48725 48726 var objects = this._objects, 48727 nObjects = objects.length, 48728 nCachedObjects = this.nCachedObjects_, 48729 indicesByUUID = this._indicesByUUID, 48730 paths = this._paths, 48731 parsedPaths = this._parsedPaths, 48732 bindings = this._bindings, 48733 nBindings = bindings.length, 48734 knownObject = undefined; 48735 48736 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 48737 48738 var object = arguments[ i ], 48739 uuid = object.uuid, 48740 index = indicesByUUID[ uuid ]; 48741 48742 if ( index === undefined ) { 48743 48744 // unknown object -> add it to the ACTIVE region 48745 48746 index = nObjects ++; 48747 indicesByUUID[ uuid ] = index; 48748 objects.push( object ); 48749 48750 // accounting is done, now do the same for all bindings 48751 48752 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 48753 48754 bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) ); 48755 48756 } 48757 48758 } else if ( index < nCachedObjects ) { 48759 48760 knownObject = objects[ index ]; 48761 48762 // move existing object to the ACTIVE region 48763 48764 var firstActiveIndex = -- nCachedObjects, 48765 lastCachedObject = objects[ firstActiveIndex ]; 48766 48767 indicesByUUID[ lastCachedObject.uuid ] = index; 48768 objects[ index ] = lastCachedObject; 48769 48770 indicesByUUID[ uuid ] = firstActiveIndex; 48771 objects[ firstActiveIndex ] = object; 48772 48773 // accounting is done, now do the same for all bindings 48774 48775 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 48776 48777 var bindingsForPath = bindings[ j ], 48778 lastCached = bindingsForPath[ firstActiveIndex ], 48779 binding = bindingsForPath[ index ]; 48780 48781 bindingsForPath[ index ] = lastCached; 48782 48783 if ( binding === undefined ) { 48784 48785 // since we do not bother to create new bindings 48786 // for objects that are cached, the binding may 48787 // or may not exist 48788 48789 binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); 48790 48791 } 48792 48793 bindingsForPath[ firstActiveIndex ] = binding; 48794 48795 } 48796 48797 } else if ( objects[ index ] !== knownObject ) { 48798 48799 console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + 48800 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); 48801 48802 } // else the object is already where we want it to be 48803 48804 } // for arguments 48805 48806 this.nCachedObjects_ = nCachedObjects; 48807 48808 }, 48809 48810 remove: function () { 48811 48812 var objects = this._objects, 48813 nCachedObjects = this.nCachedObjects_, 48814 indicesByUUID = this._indicesByUUID, 48815 bindings = this._bindings, 48816 nBindings = bindings.length; 48817 48818 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 48819 48820 var object = arguments[ i ], 48821 uuid = object.uuid, 48822 index = indicesByUUID[ uuid ]; 48823 48824 if ( index !== undefined && index >= nCachedObjects ) { 48825 48826 // move existing object into the CACHED region 48827 48828 var lastCachedIndex = nCachedObjects ++, 48829 firstActiveObject = objects[ lastCachedIndex ]; 48830 48831 indicesByUUID[ firstActiveObject.uuid ] = index; 48832 objects[ index ] = firstActiveObject; 48833 48834 indicesByUUID[ uuid ] = lastCachedIndex; 48835 objects[ lastCachedIndex ] = object; 48836 48837 // accounting is done, now do the same for all bindings 48838 48839 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 48840 48841 var bindingsForPath = bindings[ j ], 48842 firstActive = bindingsForPath[ lastCachedIndex ], 48843 binding = bindingsForPath[ index ]; 48844 48845 bindingsForPath[ index ] = firstActive; 48846 bindingsForPath[ lastCachedIndex ] = binding; 48847 48848 } 48849 48850 } 48851 48852 } // for arguments 48853 48854 this.nCachedObjects_ = nCachedObjects; 48855 48856 }, 48857 48858 // remove & forget 48859 uncache: function () { 48860 48861 var objects = this._objects, 48862 nObjects = objects.length, 48863 nCachedObjects = this.nCachedObjects_, 48864 indicesByUUID = this._indicesByUUID, 48865 bindings = this._bindings, 48866 nBindings = bindings.length; 48867 48868 for ( var i = 0, n = arguments.length; i !== n; ++ i ) { 48869 48870 var object = arguments[ i ], 48871 uuid = object.uuid, 48872 index = indicesByUUID[ uuid ]; 48873 48874 if ( index !== undefined ) { 48875 48876 delete indicesByUUID[ uuid ]; 48877 48878 if ( index < nCachedObjects ) { 48879 48880 // object is cached, shrink the CACHED region 48881 48882 var firstActiveIndex = -- nCachedObjects, 48883 lastCachedObject = objects[ firstActiveIndex ], 48884 lastIndex = -- nObjects, 48885 lastObject = objects[ lastIndex ]; 48886 48887 // last cached object takes this object's place 48888 indicesByUUID[ lastCachedObject.uuid ] = index; 48889 objects[ index ] = lastCachedObject; 48890 48891 // last object goes to the activated slot and pop 48892 indicesByUUID[ lastObject.uuid ] = firstActiveIndex; 48893 objects[ firstActiveIndex ] = lastObject; 48894 objects.pop(); 48895 48896 // accounting is done, now do the same for all bindings 48897 48898 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 48899 48900 var bindingsForPath = bindings[ j ], 48901 lastCached = bindingsForPath[ firstActiveIndex ], 48902 last = bindingsForPath[ lastIndex ]; 48903 48904 bindingsForPath[ index ] = lastCached; 48905 bindingsForPath[ firstActiveIndex ] = last; 48906 bindingsForPath.pop(); 48907 48908 } 48909 48910 } else { 48911 48912 // object is active, just swap with the last and pop 48913 48914 var lastIndex = -- nObjects, 48915 lastObject = objects[ lastIndex ]; 48916 48917 indicesByUUID[ lastObject.uuid ] = index; 48918 objects[ index ] = lastObject; 48919 objects.pop(); 48920 48921 // accounting is done, now do the same for all bindings 48922 48923 for ( var j = 0, m = nBindings; j !== m; ++ j ) { 48924 48925 var bindingsForPath = bindings[ j ]; 48926 48927 bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; 48928 bindingsForPath.pop(); 48929 48930 } 48931 48932 } // cached or active 48933 48934 } // if object is known 48935 48936 } // for arguments 48937 48938 this.nCachedObjects_ = nCachedObjects; 48939 48940 }, 48941 48942 // Internal interface used by befriended PropertyBinding.Composite: 48943 48944 subscribe_: function ( path, parsedPath ) { 48945 48946 // returns an array of bindings for the given path that is changed 48947 // according to the contained objects in the group 48948 48949 var indicesByPath = this._bindingsIndicesByPath, 48950 index = indicesByPath[ path ], 48951 bindings = this._bindings; 48952 48953 if ( index !== undefined ) return bindings[ index ]; 48954 48955 var paths = this._paths, 48956 parsedPaths = this._parsedPaths, 48957 objects = this._objects, 48958 nObjects = objects.length, 48959 nCachedObjects = this.nCachedObjects_, 48960 bindingsForPath = new Array( nObjects ); 48961 48962 index = bindings.length; 48963 48964 indicesByPath[ path ] = index; 48965 48966 paths.push( path ); 48967 parsedPaths.push( parsedPath ); 48968 bindings.push( bindingsForPath ); 48969 48970 for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) { 48971 48972 var object = objects[ i ]; 48973 bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); 48974 48975 } 48976 48977 return bindingsForPath; 48978 48979 }, 48980 48981 unsubscribe_: function ( path ) { 48982 48983 // tells the group to forget about a property path and no longer 48984 // update the array previously obtained with 'subscribe_' 48985 48986 var indicesByPath = this._bindingsIndicesByPath, 48987 index = indicesByPath[ path ]; 48988 48989 if ( index !== undefined ) { 48990 48991 var paths = this._paths, 48992 parsedPaths = this._parsedPaths, 48993 bindings = this._bindings, 48994 lastBindingsIndex = bindings.length - 1, 48995 lastBindings = bindings[ lastBindingsIndex ], 48996 lastBindingsPath = path[ lastBindingsIndex ]; 48997 48998 indicesByPath[ lastBindingsPath ] = index; 48999 49000 bindings[ index ] = lastBindings; 49001 bindings.pop(); 49002 49003 parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; 49004 parsedPaths.pop(); 49005 49006 paths[ index ] = paths[ lastBindingsIndex ]; 49007 paths.pop(); 49008 49009 } 49010 49011 } 49012 49013 } ); 49014 49015 /** 49016 * 49017 * Action provided by AnimationMixer for scheduling clip playback on specific 49018 * objects. 49019 * 49020 * @author Ben Houston / http://clara.io/ 49021 * @author David Sarno / http://lighthaus.us/ 49022 * @author tschw 49023 * 49024 */ 49025 49026 function AnimationAction( mixer, clip, localRoot ) { 49027 49028 this._mixer = mixer; 49029 this._clip = clip; 49030 this._localRoot = localRoot || null; 49031 49032 var tracks = clip.tracks, 49033 nTracks = tracks.length, 49034 interpolants = new Array( nTracks ); 49035 49036 var interpolantSettings = { 49037 endingStart: ZeroCurvatureEnding, 49038 endingEnd: ZeroCurvatureEnding 49039 }; 49040 49041 for ( var i = 0; i !== nTracks; ++ i ) { 49042 49043 var interpolant = tracks[ i ].createInterpolant( null ); 49044 interpolants[ i ] = interpolant; 49045 interpolant.settings = interpolantSettings; 49046 49047 } 49048 49049 this._interpolantSettings = interpolantSettings; 49050 49051 this._interpolants = interpolants; // bound by the mixer 49052 49053 // inside: PropertyMixer (managed by the mixer) 49054 this._propertyBindings = new Array( nTracks ); 49055 49056 this._cacheIndex = null; // for the memory manager 49057 this._byClipCacheIndex = null; // for the memory manager 49058 49059 this._timeScaleInterpolant = null; 49060 this._weightInterpolant = null; 49061 49062 this.loop = LoopRepeat; 49063 this._loopCount = - 1; 49064 49065 // global mixer time when the action is to be started 49066 // it's set back to 'null' upon start of the action 49067 this._startTime = null; 49068 49069 // scaled local time of the action 49070 // gets clamped or wrapped to 0..clip.duration according to loop 49071 this.time = 0; 49072 49073 this.timeScale = 1; 49074 this._effectiveTimeScale = 1; 49075 49076 this.weight = 1; 49077 this._effectiveWeight = 1; 49078 49079 this.repetitions = Infinity; // no. of repetitions when looping 49080 49081 this.paused = false; // true -> zero effective time scale 49082 this.enabled = true; // false -> zero effective weight 49083 49084 this.clampWhenFinished = false; // keep feeding the last frame? 49085 49086 this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate 49087 this.zeroSlopeAtEnd = true; // clips for start, loop and end 49088 49089 } 49090 49091 Object.assign( AnimationAction.prototype, { 49092 49093 // State & Scheduling 49094 49095 play: function () { 49096 49097 this._mixer._activateAction( this ); 49098 49099 return this; 49100 49101 }, 49102 49103 stop: function () { 49104 49105 this._mixer._deactivateAction( this ); 49106 49107 return this.reset(); 49108 49109 }, 49110 49111 reset: function () { 49112 49113 this.paused = false; 49114 this.enabled = true; 49115 49116 this.time = 0; // restart clip 49117 this._loopCount = - 1; // forget previous loops 49118 this._startTime = null; // forget scheduling 49119 49120 return this.stopFading().stopWarping(); 49121 49122 }, 49123 49124 isRunning: function () { 49125 49126 return this.enabled && ! this.paused && this.timeScale !== 0 && 49127 this._startTime === null && this._mixer._isActiveAction( this ); 49128 49129 }, 49130 49131 // return true when play has been called 49132 isScheduled: function () { 49133 49134 return this._mixer._isActiveAction( this ); 49135 49136 }, 49137 49138 startAt: function ( time ) { 49139 49140 this._startTime = time; 49141 49142 return this; 49143 49144 }, 49145 49146 setLoop: function ( mode, repetitions ) { 49147 49148 this.loop = mode; 49149 this.repetitions = repetitions; 49150 49151 return this; 49152 49153 }, 49154 49155 // Weight 49156 49157 // set the weight stopping any scheduled fading 49158 // although .enabled = false yields an effective weight of zero, this 49159 // method does *not* change .enabled, because it would be confusing 49160 setEffectiveWeight: function ( weight ) { 49161 49162 this.weight = weight; 49163 49164 // note: same logic as when updated at runtime 49165 this._effectiveWeight = this.enabled ? weight : 0; 49166 49167 return this.stopFading(); 49168 49169 }, 49170 49171 // return the weight considering fading and .enabled 49172 getEffectiveWeight: function () { 49173 49174 return this._effectiveWeight; 49175 49176 }, 49177 49178 fadeIn: function ( duration ) { 49179 49180 return this._scheduleFading( duration, 0, 1 ); 49181 49182 }, 49183 49184 fadeOut: function ( duration ) { 49185 49186 return this._scheduleFading( duration, 1, 0 ); 49187 49188 }, 49189 49190 crossFadeFrom: function ( fadeOutAction, duration, warp ) { 49191 49192 fadeOutAction.fadeOut( duration ); 49193 this.fadeIn( duration ); 49194 49195 if ( warp ) { 49196 49197 var fadeInDuration = this._clip.duration, 49198 fadeOutDuration = fadeOutAction._clip.duration, 49199 49200 startEndRatio = fadeOutDuration / fadeInDuration, 49201 endStartRatio = fadeInDuration / fadeOutDuration; 49202 49203 fadeOutAction.warp( 1.0, startEndRatio, duration ); 49204 this.warp( endStartRatio, 1.0, duration ); 49205 49206 } 49207 49208 return this; 49209 49210 }, 49211 49212 crossFadeTo: function ( fadeInAction, duration, warp ) { 49213 49214 return fadeInAction.crossFadeFrom( this, duration, warp ); 49215 49216 }, 49217 49218 stopFading: function () { 49219 49220 var weightInterpolant = this._weightInterpolant; 49221 49222 if ( weightInterpolant !== null ) { 49223 49224 this._weightInterpolant = null; 49225 this._mixer._takeBackControlInterpolant( weightInterpolant ); 49226 49227 } 49228 49229 return this; 49230 49231 }, 49232 49233 // Time Scale Control 49234 49235 // set the time scale stopping any scheduled warping 49236 // although .paused = true yields an effective time scale of zero, this 49237 // method does *not* change .paused, because it would be confusing 49238 setEffectiveTimeScale: function ( timeScale ) { 49239 49240 this.timeScale = timeScale; 49241 this._effectiveTimeScale = this.paused ? 0 : timeScale; 49242 49243 return this.stopWarping(); 49244 49245 }, 49246 49247 // return the time scale considering warping and .paused 49248 getEffectiveTimeScale: function () { 49249 49250 return this._effectiveTimeScale; 49251 49252 }, 49253 49254 setDuration: function ( duration ) { 49255 49256 this.timeScale = this._clip.duration / duration; 49257 49258 return this.stopWarping(); 49259 49260 }, 49261 49262 syncWith: function ( action ) { 49263 49264 this.time = action.time; 49265 this.timeScale = action.timeScale; 49266 49267 return this.stopWarping(); 49268 49269 }, 49270 49271 halt: function ( duration ) { 49272 49273 return this.warp( this._effectiveTimeScale, 0, duration ); 49274 49275 }, 49276 49277 warp: function ( startTimeScale, endTimeScale, duration ) { 49278 49279 var mixer = this._mixer, now = mixer.time, 49280 interpolant = this._timeScaleInterpolant, 49281 49282 timeScale = this.timeScale; 49283 49284 if ( interpolant === null ) { 49285 49286 interpolant = mixer._lendControlInterpolant(); 49287 this._timeScaleInterpolant = interpolant; 49288 49289 } 49290 49291 var times = interpolant.parameterPositions, 49292 values = interpolant.sampleValues; 49293 49294 times[ 0 ] = now; 49295 times[ 1 ] = now + duration; 49296 49297 values[ 0 ] = startTimeScale / timeScale; 49298 values[ 1 ] = endTimeScale / timeScale; 49299 49300 return this; 49301 49302 }, 49303
vendor: 4,213 bytes, lines 49304-49539
49304 stopWarping: function () { 49305 49306 var timeScaleInterpolant = this._timeScaleInterpolant; 49307 49308 if ( timeScaleInterpolant !== null ) { 49309 49310 this._timeScaleInterpolant = null; 49311 this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); 49312 49313 } 49314 49315 return this; 49316 49317 }, 49318 49319 // Object Accessors 49320 49321 getMixer: function () { 49322 49323 return this._mixer; 49324 49325 }, 49326 49327 getClip: function () { 49328 49329 return this._clip; 49330 49331 }, 49332 49333 getRoot: function () { 49334 49335 return this._localRoot || this._mixer._root; 49336 49337 }, 49338 49339 // Interna 49340 49341 _update: function ( time, deltaTime, timeDirection, accuIndex ) { 49342 49343 // called by the mixer 49344 49345 if ( ! this.enabled ) { 49346 49347 // call ._updateWeight() to update ._effectiveWeight 49348 49349 this._updateWeight( time ); 49350 return; 49351 49352 } 49353 49354 var startTime = this._startTime; 49355 49356 if ( startTime !== null ) { 49357 49358 // check for scheduled start of action 49359 49360 var timeRunning = ( time - startTime ) * timeDirection; 49361 if ( timeRunning < 0 || timeDirection === 0 ) { 49362 49363 return; // yet to come / don't decide when delta = 0 49364 49365 } 49366 49367 // start 49368 49369 this._startTime = null; // unschedule 49370 deltaTime = timeDirection * timeRunning; 49371 49372 } 49373 49374 // apply time scale and advance time 49375 49376 deltaTime *= this._updateTimeScale( time ); 49377 var clipTime = this._updateTime( deltaTime ); 49378 49379 // note: _updateTime may disable the action resulting in 49380 // an effective weight of 0 49381 49382 var weight = this._updateWeight( time ); 49383 49384 if ( weight > 0 ) { 49385 49386 var interpolants = this._interpolants; 49387 var propertyMixers = this._propertyBindings; 49388 49389 for ( var j = 0, m = interpolants.length; j !== m; ++ j ) { 49390 49391 interpolants[ j ].evaluate( clipTime ); 49392 propertyMixers[ j ].accumulate( accuIndex, weight ); 49393 49394 } 49395 49396 } 49397 49398 }, 49399 49400 _updateWeight: function ( time ) { 49401 49402 var weight = 0; 49403 49404 if ( this.enabled ) { 49405 49406 weight = this.weight; 49407 var interpolant = this._weightInterpolant; 49408 49409 if ( interpolant !== null ) { 49410 49411 var interpolantValue = interpolant.evaluate( time )[ 0 ]; 49412 49413 weight *= interpolantValue; 49414 49415 if ( time > interpolant.parameterPositions[ 1 ] ) { 49416 49417 this.stopFading(); 49418 49419 if ( interpolantValue === 0 ) { 49420 49421 // faded out, disable 49422 this.enabled = false; 49423 49424 } 49425 49426 } 49427 49428 } 49429 49430 } 49431 49432 this._effectiveWeight = weight; 49433 return weight; 49434 49435 }, 49436 49437 _updateTimeScale: function ( time ) { 49438 49439 var timeScale = 0; 49440 49441 if ( ! this.paused ) { 49442 49443 timeScale = this.timeScale; 49444 49445 var interpolant = this._timeScaleInterpolant; 49446 49447 if ( interpolant !== null ) { 49448 49449 var interpolantValue = interpolant.evaluate( time )[ 0 ]; 49450 49451 timeScale *= interpolantValue; 49452 49453 if ( time > interpolant.parameterPositions[ 1 ] ) { 49454 49455 this.stopWarping(); 49456 49457 if ( timeScale === 0 ) { 49458 49459 // motion has halted, pause 49460 this.paused = true; 49461 49462 } else { 49463 49464 // warp done - apply final time scale 49465 this.timeScale = timeScale; 49466 49467 } 49468 49469 } 49470 49471 } 49472 49473 } 49474 49475 this._effectiveTimeScale = timeScale; 49476 return timeScale; 49477 49478 }, 49479 49480 _updateTime: function ( deltaTime ) { 49481 49482 var time = this.time + deltaTime; 49483 49484 if ( deltaTime === 0 ) return time; 49485 49486 var duration = this._clip.duration, 49487 49488 loop = this.loop, 49489 loopCount = this._loopCount; 49490 49491 if ( loop === LoopOnce ) { 49492 49493 if ( loopCount === - 1 ) { 49494 49495 // just started 49496 49497 this._loopCount = 0; 49498 this._setEndings( true, true, false ); 49499 49500 } 49501 49502 handle_stop: { 49503 49504 if ( time >= duration ) { 49505 49506 time = duration; 49507 49508 } else if ( time < 0 ) { 49509 49510 time = 0; 49511 49512 } else break handle_stop; 49513 49514 if ( this.clampWhenFinished ) this.paused = true; 49515 else this.enabled = false; 49516 49517 this._mixer.dispatchEvent( { 49518 type: 'finished', action: this, 49519 direction: deltaTime < 0 ? - 1 : 1 49520 } ); 49521 49522 } 49523 49524 } else { // repetitive Repeat or PingPong 49525 49526 var pingPong = ( loop === LoopPingPong ); 49527 49528 if ( loopCount === - 1 ) { 49529 49530 // just started 49531 49532 if ( deltaTime >= 0 ) { 49533 49534 loopCount = 0; 49535 49536 this._setEndings( true, this.repetitions === 0, pingPong ); 49537 49538 } else { 49539
vendor: 8,768 bytes, lines 49540-49968
49540 // when looping in reverse direction, the initial 49541 // transition through zero counts as a repetition, 49542 // so leave loopCount at -1 49543 49544 this._setEndings( this.repetitions === 0, true, pingPong ); 49545 49546 } 49547 49548 } 49549 49550 if ( time >= duration || time < 0 ) { 49551 49552 // wrap around 49553 49554 var loopDelta = Math.floor( time / duration ); // signed 49555 time -= duration * loopDelta; 49556 49557 loopCount += Math.abs( loopDelta ); 49558 49559 var pending = this.repetitions - loopCount; 49560 49561 if ( pending <= 0 ) { 49562 49563 // have to stop (switch state, clamp time, fire event) 49564 49565 if ( this.clampWhenFinished ) this.paused = true; 49566 else this.enabled = false; 49567 49568 time = deltaTime > 0 ? duration : 0; 49569 49570 this._mixer.dispatchEvent( { 49571 type: 'finished', action: this, 49572 direction: deltaTime > 0 ? 1 : - 1 49573 } ); 49574 49575 } else { 49576 49577 // keep running 49578 49579 if ( pending === 1 ) { 49580 49581 // entering the last round 49582 49583 var atStart = deltaTime < 0; 49584 this._setEndings( atStart, ! atStart, pingPong ); 49585 49586 } else { 49587 49588 this._setEndings( false, false, pingPong ); 49589 49590 } 49591 49592 this._loopCount = loopCount; 49593 49594 this._mixer.dispatchEvent( { 49595 type: 'loop', action: this, loopDelta: loopDelta 49596 } ); 49597 49598 } 49599 49600 } 49601 49602 if ( pingPong && ( loopCount & 1 ) === 1 ) { 49603 49604 // invert time for the "pong round" 49605 49606 this.time = time; 49607 return duration - time; 49608 49609 } 49610 49611 } 49612 49613 this.time = time; 49614 return time; 49615 49616 }, 49617 49618 _setEndings: function ( atStart, atEnd, pingPong ) { 49619 49620 var settings = this._interpolantSettings; 49621 49622 if ( pingPong ) { 49623 49624 settings.endingStart = ZeroSlopeEnding; 49625 settings.endingEnd = ZeroSlopeEnding; 49626 49627 } else { 49628 49629 // assuming for LoopOnce atStart == atEnd == true 49630 49631 if ( atStart ) { 49632 49633 settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; 49634 49635 } else { 49636 49637 settings.endingStart = WrapAroundEnding; 49638 49639 } 49640 49641 if ( atEnd ) { 49642 49643 settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; 49644 49645 } else { 49646 49647 settings.endingEnd = WrapAroundEnding; 49648 49649 } 49650 49651 } 49652 49653 }, 49654 49655 _scheduleFading: function ( duration, weightNow, weightThen ) { 49656 49657 var mixer = this._mixer, now = mixer.time, 49658 interpolant = this._weightInterpolant; 49659 49660 if ( interpolant === null ) { 49661 49662 interpolant = mixer._lendControlInterpolant(); 49663 this._weightInterpolant = interpolant; 49664 49665 } 49666 49667 var times = interpolant.parameterPositions, 49668 values = interpolant.sampleValues; 49669 49670 times[ 0 ] = now; values[ 0 ] = weightNow; 49671 times[ 1 ] = now + duration; values[ 1 ] = weightThen; 49672 49673 return this; 49674 49675 } 49676 49677 } ); 49678 49679 /** 49680 * 49681 * Player for AnimationClips. 49682 * 49683 * 49684 * @author Ben Houston / http://clara.io/ 49685 * @author David Sarno / http://lighthaus.us/ 49686 * @author tschw 49687 */ 49688 49689 function AnimationMixer( root ) { 49690 49691 this._root = root; 49692 this._initMemoryManager(); 49693 this._accuIndex = 0; 49694 49695 this.time = 0; 49696 49697 this.timeScale = 1.0; 49698 49699 } 49700 49701 AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { 49702 49703 constructor: AnimationMixer, 49704 49705 _bindAction: function ( action, prototypeAction ) { 49706 49707 var root = action._localRoot || this._root, 49708 tracks = action._clip.tracks, 49709 nTracks = tracks.length, 49710 bindings = action._propertyBindings, 49711 interpolants = action._interpolants, 49712 rootUuid = root.uuid, 49713 bindingsByRoot = this._bindingsByRootAndName, 49714 bindingsByName = bindingsByRoot[ rootUuid ]; 49715 49716 if ( bindingsByName === undefined ) { 49717 49718 bindingsByName = {}; 49719 bindingsByRoot[ rootUuid ] = bindingsByName; 49720 49721 } 49722 49723 for ( var i = 0; i !== nTracks; ++ i ) { 49724 49725 var track = tracks[ i ], 49726 trackName = track.name, 49727 binding = bindingsByName[ trackName ]; 49728 49729 if ( binding !== undefined ) { 49730 49731 bindings[ i ] = binding; 49732 49733 } else { 49734 49735 binding = bindings[ i ]; 49736 49737 if ( binding !== undefined ) { 49738 49739 // existing binding, make sure the cache knows 49740 49741 if ( binding._cacheIndex === null ) { 49742 49743 ++ binding.referenceCount; 49744 this._addInactiveBinding( binding, rootUuid, trackName ); 49745 49746 } 49747 49748 continue; 49749 49750 } 49751 49752 var path = prototypeAction && prototypeAction. 49753 _propertyBindings[ i ].binding.parsedPath; 49754 49755 binding = new PropertyMixer( 49756 PropertyBinding.create( root, trackName, path ), 49757 track.ValueTypeName, track.getValueSize() ); 49758 49759 ++ binding.referenceCount; 49760 this._addInactiveBinding( binding, rootUuid, trackName ); 49761 49762 bindings[ i ] = binding; 49763 49764 } 49765 49766 interpolants[ i ].resultBuffer = binding.buffer; 49767 49768 } 49769 49770 }, 49771 49772 _activateAction: function ( action ) { 49773 49774 if ( ! this._isActiveAction( action ) ) { 49775 49776 if ( action._cacheIndex === null ) { 49777 49778 // this action has been forgotten by the cache, but the user 49779 // appears to be still using it -> rebind 49780 49781 var rootUuid = ( action._localRoot || this._root ).uuid, 49782 clipUuid = action._clip.uuid, 49783 actionsForClip = this._actionsByClip[ clipUuid ]; 49784 49785 this._bindAction( action, 49786 actionsForClip && actionsForClip.knownActions[ 0 ] ); 49787 49788 this._addInactiveAction( action, clipUuid, rootUuid ); 49789 49790 } 49791 49792 var bindings = action._propertyBindings; 49793 49794 // increment reference counts / sort out state 49795 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 49796 49797 var binding = bindings[ i ]; 49798 49799 if ( binding.useCount ++ === 0 ) { 49800 49801 this._lendBinding( binding ); 49802 binding.saveOriginalState(); 49803 49804 } 49805 49806 } 49807 49808 this._lendAction( action ); 49809 49810 } 49811 49812 }, 49813 49814 _deactivateAction: function ( action ) { 49815 49816 if ( this._isActiveAction( action ) ) { 49817 49818 var bindings = action._propertyBindings; 49819 49820 // decrement reference counts / sort out state 49821 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 49822 49823 var binding = bindings[ i ]; 49824 49825 if ( -- binding.useCount === 0 ) { 49826 49827 binding.restoreOriginalState(); 49828 this._takeBackBinding( binding ); 49829 49830 } 49831 49832 } 49833 49834 this._takeBackAction( action ); 49835 49836 } 49837 49838 }, 49839 49840 // Memory manager 49841 49842 _initMemoryManager: function () { 49843 49844 this._actions = []; // 'nActiveActions' followed by inactive ones 49845 this._nActiveActions = 0; 49846 49847 this._actionsByClip = {}; 49848 // inside: 49849 // { 49850 // knownActions: Array< AnimationAction > - used as prototypes 49851 // actionByRoot: AnimationAction - lookup 49852 // } 49853 49854 49855 this._bindings = []; // 'nActiveBindings' followed by inactive ones 49856 this._nActiveBindings = 0; 49857 49858 this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > 49859 49860 49861 this._controlInterpolants = []; // same game as above 49862 this._nActiveControlInterpolants = 0; 49863 49864 var scope = this; 49865 49866 this.stats = { 49867 49868 actions: { 49869 get total() { 49870 49871 return scope._actions.length; 49872 49873 }, 49874 get inUse() { 49875 49876 return scope._nActiveActions; 49877 49878 } 49879 }, 49880 bindings: { 49881 get total() { 49882 49883 return scope._bindings.length; 49884 49885 }, 49886 get inUse() { 49887 49888 return scope._nActiveBindings; 49889 49890 } 49891 }, 49892 controlInterpolants: { 49893 get total() { 49894 49895 return scope._controlInterpolants.length; 49896 49897 }, 49898 get inUse() { 49899 49900 return scope._nActiveControlInterpolants; 49901 49902 } 49903 } 49904 49905 }; 49906 49907 }, 49908 49909 // Memory management for AnimationAction objects 49910 49911 _isActiveAction: function ( action ) { 49912 49913 var index = action._cacheIndex; 49914 return index !== null && index < this._nActiveActions; 49915 49916 }, 49917 49918 _addInactiveAction: function ( action, clipUuid, rootUuid ) { 49919 49920 var actions = this._actions, 49921 actionsByClip = this._actionsByClip, 49922 actionsForClip = actionsByClip[ clipUuid ]; 49923 49924 if ( actionsForClip === undefined ) { 49925 49926 actionsForClip = { 49927 49928 knownActions: [ action ], 49929 actionByRoot: {} 49930 49931 }; 49932 49933 action._byClipCacheIndex = 0; 49934 49935 actionsByClip[ clipUuid ] = actionsForClip; 49936 49937 } else { 49938 49939 var knownActions = actionsForClip.knownActions; 49940 49941 action._byClipCacheIndex = knownActions.length; 49942 knownActions.push( action ); 49943 49944 } 49945 49946 action._cacheIndex = actions.length; 49947 actions.push( action ); 49948 49949 actionsForClip.actionByRoot[ rootUuid ] = action; 49950 49951 }, 49952 49953 _removeInactiveAction: function ( action ) { 49954 49955 var actions = this._actions, 49956 lastInactiveAction = actions[ actions.length - 1 ], 49957 cacheIndex = action._cacheIndex; 49958 49959 lastInactiveAction._cacheIndex = cacheIndex; 49960 actions[ cacheIndex ] = lastInactiveAction; 49961 actions.pop(); 49962 49963 action._cacheIndex = null; 49964 49965 49966 var clipUuid = action._clip.uuid, 49967 actionsByClip = this._actionsByClip, 49968 actionsForClip = actionsByClip[ clipUuid ],
vendor: 4,311 bytes, lines 49969-50145
49969 knownActionsForClip = actionsForClip.knownActions, 49970 49971 lastKnownAction = 49972 knownActionsForClip[ knownActionsForClip.length - 1 ], 49973 49974 byClipCacheIndex = action._byClipCacheIndex; 49975 49976 lastKnownAction._byClipCacheIndex = byClipCacheIndex; 49977 knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; 49978 knownActionsForClip.pop(); 49979 49980 action._byClipCacheIndex = null; 49981 49982 49983 var actionByRoot = actionsForClip.actionByRoot, 49984 rootUuid = ( action._localRoot || this._root ).uuid; 49985 49986 delete actionByRoot[ rootUuid ]; 49987 49988 if ( knownActionsForClip.length === 0 ) { 49989 49990 delete actionsByClip[ clipUuid ]; 49991 49992 } 49993 49994 this._removeInactiveBindingsForAction( action ); 49995 49996 }, 49997 49998 _removeInactiveBindingsForAction: function ( action ) { 49999 50000 var bindings = action._propertyBindings; 50001 for ( var i = 0, n = bindings.length; i !== n; ++ i ) { 50002 50003 var binding = bindings[ i ]; 50004 50005 if ( -- binding.referenceCount === 0 ) { 50006 50007 this._removeInactiveBinding( binding ); 50008 50009 } 50010 50011 } 50012 50013 }, 50014 50015 _lendAction: function ( action ) { 50016 50017 // [ active actions | inactive actions ] 50018 // [ active actions >| inactive actions ] 50019 // s a 50020 // <-swap-> 50021 // a s 50022 50023 var actions = this._actions, 50024 prevIndex = action._cacheIndex, 50025 50026 lastActiveIndex = this._nActiveActions ++, 50027 50028 firstInactiveAction = actions[ lastActiveIndex ]; 50029 50030 action._cacheIndex = lastActiveIndex; 50031 actions[ lastActiveIndex ] = action; 50032 50033 firstInactiveAction._cacheIndex = prevIndex; 50034 actions[ prevIndex ] = firstInactiveAction; 50035 50036 }, 50037 50038 _takeBackAction: function ( action ) { 50039 50040 // [ active actions | inactive actions ] 50041 // [ active actions |< inactive actions ] 50042 // a s 50043 // <-swap-> 50044 // s a 50045 50046 var actions = this._actions, 50047 prevIndex = action._cacheIndex, 50048 50049 firstInactiveIndex = -- this._nActiveActions, 50050 50051 lastActiveAction = actions[ firstInactiveIndex ]; 50052 50053 action._cacheIndex = firstInactiveIndex; 50054 actions[ firstInactiveIndex ] = action; 50055 50056 lastActiveAction._cacheIndex = prevIndex; 50057 actions[ prevIndex ] = lastActiveAction; 50058 50059 }, 50060 50061 // Memory management for PropertyMixer objects 50062 50063 _addInactiveBinding: function ( binding, rootUuid, trackName ) { 50064 50065 var bindingsByRoot = this._bindingsByRootAndName, 50066 bindingByName = bindingsByRoot[ rootUuid ], 50067 50068 bindings = this._bindings; 50069 50070 if ( bindingByName === undefined ) { 50071 50072 bindingByName = {}; 50073 bindingsByRoot[ rootUuid ] = bindingByName; 50074 50075 } 50076 50077 bindingByName[ trackName ] = binding; 50078 50079 binding._cacheIndex = bindings.length; 50080 bindings.push( binding ); 50081 50082 }, 50083 50084 _removeInactiveBinding: function ( binding ) { 50085 50086 var bindings = this._bindings, 50087 propBinding = binding.binding, 50088 rootUuid = propBinding.rootNode.uuid, 50089 trackName = propBinding.path, 50090 bindingsByRoot = this._bindingsByRootAndName, 50091 bindingByName = bindingsByRoot[ rootUuid ], 50092 50093 lastInactiveBinding = bindings[ bindings.length - 1 ], 50094 cacheIndex = binding._cacheIndex; 50095 50096 lastInactiveBinding._cacheIndex = cacheIndex; 50097 bindings[ cacheIndex ] = lastInactiveBinding; 50098 bindings.pop(); 50099 50100 delete bindingByName[ trackName ]; 50101 50102 remove_empty_map: { 50103 50104 for ( var _ in bindingByName ) break remove_empty_map; // eslint-disable-line no-unused-vars 50105 50106 delete bindingsByRoot[ rootUuid ]; 50107 50108 } 50109 50110 }, 50111 50112 _lendBinding: function ( binding ) { 50113 50114 var bindings = this._bindings, 50115 prevIndex = binding._cacheIndex, 50116 50117 lastActiveIndex = this._nActiveBindings ++, 50118 50119 firstInactiveBinding = bindings[ lastActiveIndex ]; 50120 50121 binding._cacheIndex = lastActiveIndex; 50122 bindings[ lastActiveIndex ] = binding; 50123 50124 firstInactiveBinding._cacheIndex = prevIndex; 50125 bindings[ prevIndex ] = firstInactiveBinding; 50126 50127 }, 50128 50129 _takeBackBinding: function ( binding ) { 50130 50131 var bindings = this._bindings, 50132 prevIndex = binding._cacheIndex, 50133 50134 firstInactiveIndex = -- this._nActiveBindings, 50135 50136 lastActiveBinding = bindings[ firstInactiveIndex ]; 50137 50138 binding._cacheIndex = firstInactiveIndex; 50139 bindings[ firstInactiveIndex ] = binding; 50140 50141 lastActiveBinding._cacheIndex = prevIndex; 50142 bindings[ prevIndex ] = lastActiveBinding; 50143 50144 }, 50145
vendor: 17,907 bytes, lines 50146-51017
50146 50147 // Memory management of Interpolants for weight and time scale 50148 50149 _lendControlInterpolant: function () { 50150 50151 var interpolants = this._controlInterpolants, 50152 lastActiveIndex = this._nActiveControlInterpolants ++, 50153 interpolant = interpolants[ lastActiveIndex ]; 50154 50155 if ( interpolant === undefined ) { 50156 50157 interpolant = new LinearInterpolant( 50158 new Float32Array( 2 ), new Float32Array( 2 ), 50159 1, this._controlInterpolantsResultBuffer ); 50160 50161 interpolant.__cacheIndex = lastActiveIndex; 50162 interpolants[ lastActiveIndex ] = interpolant; 50163 50164 } 50165 50166 return interpolant; 50167 50168 }, 50169 50170 _takeBackControlInterpolant: function ( interpolant ) { 50171 50172 var interpolants = this._controlInterpolants, 50173 prevIndex = interpolant.__cacheIndex, 50174 50175 firstInactiveIndex = -- this._nActiveControlInterpolants, 50176 50177 lastActiveInterpolant = interpolants[ firstInactiveIndex ]; 50178 50179 interpolant.__cacheIndex = firstInactiveIndex; 50180 interpolants[ firstInactiveIndex ] = interpolant; 50181 50182 lastActiveInterpolant.__cacheIndex = prevIndex; 50183 interpolants[ prevIndex ] = lastActiveInterpolant; 50184 50185 }, 50186 50187 _controlInterpolantsResultBuffer: new Float32Array( 1 ), 50188 50189 // return an action for a clip optionally using a custom root target 50190 // object (this method allocates a lot of dynamic memory in case a 50191 // previously unknown clip/root combination is specified) 50192 clipAction: function ( clip, optionalRoot ) { 50193 50194 var root = optionalRoot || this._root, 50195 rootUuid = root.uuid, 50196 50197 clipObject = typeof clip === 'string' ? 50198 AnimationClip.findByName( root, clip ) : clip, 50199 50200 clipUuid = clipObject !== null ? clipObject.uuid : clip, 50201 50202 actionsForClip = this._actionsByClip[ clipUuid ], 50203 prototypeAction = null; 50204 50205 if ( actionsForClip !== undefined ) { 50206 50207 var existingAction = 50208 actionsForClip.actionByRoot[ rootUuid ]; 50209 50210 if ( existingAction !== undefined ) { 50211 50212 return existingAction; 50213 50214 } 50215 50216 // we know the clip, so we don't have to parse all 50217 // the bindings again but can just copy 50218 prototypeAction = actionsForClip.knownActions[ 0 ]; 50219 50220 // also, take the clip from the prototype action 50221 if ( clipObject === null ) 50222 clipObject = prototypeAction._clip; 50223 50224 } 50225 50226 // clip must be known when specified via string 50227 if ( clipObject === null ) return null; 50228 50229 // allocate all resources required to run it 50230 var newAction = new AnimationAction( this, clipObject, optionalRoot ); 50231 50232 this._bindAction( newAction, prototypeAction ); 50233 50234 // and make the action known to the memory manager 50235 this._addInactiveAction( newAction, clipUuid, rootUuid ); 50236 50237 return newAction; 50238 50239 }, 50240 50241 // get an existing action 50242 existingAction: function ( clip, optionalRoot ) { 50243 50244 var root = optionalRoot || this._root, 50245 rootUuid = root.uuid, 50246 50247 clipObject = typeof clip === 'string' ? 50248 AnimationClip.findByName( root, clip ) : clip, 50249 50250 clipUuid = clipObject ? clipObject.uuid : clip, 50251 50252 actionsForClip = this._actionsByClip[ clipUuid ]; 50253 50254 if ( actionsForClip !== undefined ) { 50255 50256 return actionsForClip.actionByRoot[ rootUuid ] || null; 50257 50258 } 50259 50260 return null; 50261 50262 }, 50263 50264 // deactivates all previously scheduled actions 50265 stopAllAction: function () { 50266 50267 var actions = this._actions, 50268 nActions = this._nActiveActions, 50269 bindings = this._bindings, 50270 nBindings = this._nActiveBindings; 50271 50272 this._nActiveActions = 0; 50273 this._nActiveBindings = 0; 50274 50275 for ( var i = 0; i !== nActions; ++ i ) { 50276 50277 actions[ i ].reset(); 50278 50279 } 50280 50281 for ( var i = 0; i !== nBindings; ++ i ) { 50282 50283 bindings[ i ].useCount = 0; 50284 50285 } 50286 50287 return this; 50288 50289 }, 50290 50291 // advance the time and update apply the animation 50292 update: function ( deltaTime ) { 50293 50294 deltaTime *= this.timeScale; 50295 50296 var actions = this._actions, 50297 nActions = this._nActiveActions, 50298 50299 time = this.time += deltaTime, 50300 timeDirection = Math.sign( deltaTime ), 50301 50302 accuIndex = this._accuIndex ^= 1; 50303 50304 // run active actions 50305 50306 for ( var i = 0; i !== nActions; ++ i ) { 50307 50308 var action = actions[ i ]; 50309 50310 action._update( time, deltaTime, timeDirection, accuIndex ); 50311 50312 } 50313 50314 // update scene graph 50315 50316 var bindings = this._bindings, 50317 nBindings = this._nActiveBindings; 50318 50319 for ( var i = 0; i !== nBindings; ++ i ) { 50320 50321 bindings[ i ].apply( accuIndex ); 50322 50323 } 50324 50325 return this; 50326 50327 }, 50328 50329 // return this mixer's root target object 50330 getRoot: function () { 50331 50332 return this._root; 50333 50334 }, 50335 50336 // free all resources specific to a particular clip 50337 uncacheClip: function ( clip ) { 50338 50339 var actions = this._actions, 50340 clipUuid = clip.uuid, 50341 actionsByClip = this._actionsByClip, 50342 actionsForClip = actionsByClip[ clipUuid ]; 50343 50344 if ( actionsForClip !== undefined ) { 50345 50346 // note: just calling _removeInactiveAction would mess up the 50347 // iteration state and also require updating the state we can 50348 // just throw away 50349 50350 var actionsToRemove = actionsForClip.knownActions; 50351 50352 for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { 50353 50354 var action = actionsToRemove[ i ]; 50355 50356 this._deactivateAction( action ); 50357 50358 var cacheIndex = action._cacheIndex, 50359 lastInactiveAction = actions[ actions.length - 1 ]; 50360 50361 action._cacheIndex = null; 50362 action._byClipCacheIndex = null; 50363 50364 lastInactiveAction._cacheIndex = cacheIndex; 50365 actions[ cacheIndex ] = lastInactiveAction; 50366 actions.pop(); 50367 50368 this._removeInactiveBindingsForAction( action ); 50369 50370 } 50371 50372 delete actionsByClip[ clipUuid ]; 50373 50374 } 50375 50376 }, 50377 50378 // free all resources specific to a particular root target object 50379 uncacheRoot: function ( root ) { 50380 50381 var rootUuid = root.uuid, 50382 actionsByClip = this._actionsByClip; 50383 50384 for ( var clipUuid in actionsByClip ) { 50385 50386 var actionByRoot = actionsByClip[ clipUuid ].actionByRoot, 50387 action = actionByRoot[ rootUuid ]; 50388 50389 if ( action !== undefined ) { 50390 50391 this._deactivateAction( action ); 50392 this._removeInactiveAction( action ); 50393 50394 } 50395 50396 } 50397 50398 var bindingsByRoot = this._bindingsByRootAndName, 50399 bindingByName = bindingsByRoot[ rootUuid ]; 50400 50401 if ( bindingByName !== undefined ) { 50402 50403 for ( var trackName in bindingByName ) { 50404 50405 var binding = bindingByName[ trackName ]; 50406 binding.restoreOriginalState(); 50407 this._removeInactiveBinding( binding ); 50408 50409 } 50410 50411 } 50412 50413 }, 50414 50415 // remove a targeted clip from the cache 50416 uncacheAction: function ( clip, optionalRoot ) { 50417 50418 var action = this.existingAction( clip, optionalRoot ); 50419 50420 if ( action !== null ) { 50421 50422 this._deactivateAction( action ); 50423 this._removeInactiveAction( action ); 50424 50425 } 50426 50427 } 50428 50429 } ); 50430 50431 /** 50432 * @author mrdoob / http://mrdoob.com/ 50433 */ 50434 50435 function Uniform( value ) { 50436 50437 if ( typeof value === 'string' ) { 50438 50439 console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); 50440 value = arguments[ 1 ]; 50441 50442 } 50443 50444 this.value = value; 50445 50446 } 50447 50448 Uniform.prototype.clone = function () { 50449 50450 return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); 50451 50452 }; 50453 50454 /** 50455 * @author benaadams / https://twitter.com/ben_a_adams 50456 */ 50457 50458 function InstancedBufferGeometry() { 50459 50460 BufferGeometry.call( this ); 50461 50462 this.type = 'InstancedBufferGeometry'; 50463 this.maxInstancedCount = undefined; 50464 50465 } 50466 50467 InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), { 50468 50469 constructor: InstancedBufferGeometry, 50470 50471 isInstancedBufferGeometry: true, 50472 50473 copy: function ( source ) { 50474 50475 BufferGeometry.prototype.copy.call( this, source ); 50476 50477 this.maxInstancedCount = source.maxInstancedCount; 50478 50479 return this; 50480 50481 }, 50482 50483 clone: function () { 50484 50485 return new this.constructor().copy( this ); 50486 50487 } 50488 50489 } ); 50490 50491 /** 50492 * @author benaadams / https://twitter.com/ben_a_adams 50493 */ 50494 50495 function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { 50496 50497 this.data = interleavedBuffer; 50498 this.itemSize = itemSize; 50499 this.offset = offset; 50500 50501 this.normalized = normalized === true; 50502 50503 } 50504 50505 Object.defineProperties( InterleavedBufferAttribute.prototype, { 50506 50507 count: { 50508 50509 get: function () { 50510 50511 return this.data.count; 50512 50513 } 50514 50515 }, 50516 50517 array: { 50518 50519 get: function () { 50520 50521 return this.data.array; 50522 50523 } 50524 50525 } 50526 50527 } ); 50528 50529 Object.assign( InterleavedBufferAttribute.prototype, { 50530 50531 isInterleavedBufferAttribute: true, 50532 50533 setX: function ( index, x ) { 50534 50535 this.data.array[ index * this.data.stride + this.offset ] = x; 50536 50537 return this; 50538 50539 }, 50540 50541 setY: function ( index, y ) { 50542 50543 this.data.array[ index * this.data.stride + this.offset + 1 ] = y; 50544 50545 return this; 50546 50547 }, 50548 50549 setZ: function ( index, z ) { 50550 50551 this.data.array[ index * this.data.stride + this.offset + 2 ] = z; 50552 50553 return this; 50554 50555 }, 50556 50557 setW: function ( index, w ) { 50558 50559 this.data.array[ index * this.data.stride + this.offset + 3 ] = w; 50560 50561 return this; 50562 50563 }, 50564 50565 getX: function ( index ) { 50566 50567 return this.data.array[ index * this.data.stride + this.offset ]; 50568 50569 }, 50570 50571 getY: function ( index ) { 50572 50573 return this.data.array[ index * this.data.stride + this.offset + 1 ]; 50574 50575 }, 50576 50577 getZ: function ( index ) { 50578 50579 return this.data.array[ index * this.data.stride + this.offset + 2 ]; 50580 50581 }, 50582 50583 getW: function ( index ) { 50584 50585 return this.data.array[ index * this.data.stride + this.offset + 3 ]; 50586 50587 }, 50588 50589 setXY: function ( index, x, y ) { 50590 50591 index = index * this.data.stride + this.offset; 50592 50593 this.data.array[ index + 0 ] = x; 50594 this.data.array[ index + 1 ] = y; 50595 50596 return this; 50597 50598 }, 50599 50600 setXYZ: function ( index, x, y, z ) { 50601 50602 index = index * this.data.stride + this.offset; 50603 50604 this.data.array[ index + 0 ] = x; 50605 this.data.array[ index + 1 ] = y; 50606 this.data.array[ index + 2 ] = z; 50607 50608 return this; 50609 50610 }, 50611 50612 setXYZW: function ( index, x, y, z, w ) { 50613 50614 index = index * this.data.stride + this.offset; 50615 50616 this.data.array[ index + 0 ] = x; 50617 this.data.array[ index + 1 ] = y; 50618 this.data.array[ index + 2 ] = z; 50619 this.data.array[ index + 3 ] = w; 50620 50621 return this; 50622 50623 } 50624 50625 } ); 50626 50627 /** 50628 * @author benaadams / https://twitter.com/ben_a_adams 50629 */ 50630 50631 function InterleavedBuffer( array, stride ) { 50632 50633 this.array = array; 50634 this.stride = stride; 50635 this.count = array !== undefined ? array.length / stride : 0; 50636 50637 this.dynamic = false; 50638 this.updateRange = { offset: 0, count: - 1 }; 50639 50640 this.version = 0; 50641 50642 } 50643 50644 Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', { 50645 50646 set: function ( value ) { 50647 50648 if ( value === true ) this.version ++; 50649 50650 } 50651 50652 } ); 50653 50654 Object.assign( InterleavedBuffer.prototype, { 50655 50656 isInterleavedBuffer: true, 50657 50658 onUploadCallback: function () {}, 50659 50660 setArray: function ( array ) { 50661 50662 if ( Array.isArray( array ) ) { 50663 50664 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); 50665 50666 } 50667 50668 this.count = array !== undefined ? array.length / this.stride : 0; 50669 this.array = array; 50670 50671 return this; 50672 50673 }, 50674 50675 setDynamic: function ( value ) { 50676 50677 this.dynamic = value; 50678 50679 return this; 50680 50681 }, 50682 50683 copy: function ( source ) { 50684 50685 this.array = new source.array.constructor( source.array ); 50686 this.count = source.count; 50687 this.stride = source.stride; 50688 this.dynamic = source.dynamic; 50689 50690 return this; 50691 50692 }, 50693 50694 copyAt: function ( index1, attribute, index2 ) { 50695 50696 index1 *= this.stride; 50697 index2 *= attribute.stride; 50698 50699 for ( var i = 0, l = this.stride; i < l; i ++ ) { 50700 50701 this.array[ index1 + i ] = attribute.array[ index2 + i ]; 50702 50703 } 50704 50705 return this; 50706 50707 }, 50708 50709 set: function ( value, offset ) { 50710 50711 if ( offset === undefined ) offset = 0; 50712 50713 this.array.set( value, offset ); 50714 50715 return this; 50716 50717 }, 50718 50719 clone: function () { 50720 50721 return new this.constructor().copy( this ); 50722 50723 }, 50724 50725 onUpload: function ( callback ) { 50726 50727 this.onUploadCallback = callback; 50728 50729 return this; 50730 50731 } 50732 50733 } ); 50734 50735 /** 50736 * @author benaadams / https://twitter.com/ben_a_adams 50737 */ 50738 50739 function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) { 50740 50741 InterleavedBuffer.call( this, array, stride ); 50742 50743 this.meshPerAttribute = meshPerAttribute || 1; 50744 50745 } 50746 50747 InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), { 50748 50749 constructor: InstancedInterleavedBuffer, 50750 50751 isInstancedInterleavedBuffer: true, 50752 50753 copy: function ( source ) { 50754 50755 InterleavedBuffer.prototype.copy.call( this, source ); 50756 50757 this.meshPerAttribute = source.meshPerAttribute; 50758 50759 return this; 50760 50761 } 50762 50763 } ); 50764 50765 /** 50766 * @author benaadams / https://twitter.com/ben_a_adams 50767 */ 50768 50769 function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) { 50770 50771 BufferAttribute.call( this, array, itemSize ); 50772 50773 this.meshPerAttribute = meshPerAttribute || 1; 50774 50775 } 50776 50777 InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), { 50778 50779 constructor: InstancedBufferAttribute, 50780 50781 isInstancedBufferAttribute: true, 50782 50783 copy: function ( source ) { 50784 50785 BufferAttribute.prototype.copy.call( this, source ); 50786 50787 this.meshPerAttribute = source.meshPerAttribute; 50788 50789 return this; 50790 50791 } 50792 50793 } ); 50794 50795 /** 50796 * @author mrdoob / http://mrdoob.com/ 50797 * @author bhouston / http://clara.io/ 50798 * @author stephomi / http://stephaneginier.com/ 50799 */ 50800 50801 function Raycaster( origin, direction, near, far ) { 50802 50803 this.ray = new Ray( origin, direction ); 50804 // direction is assumed to be normalized (for accurate distance calculations) 50805 50806 this.near = near || 0; 50807 this.far = far || Infinity; 50808 50809 this.params = { 50810 Mesh: {}, 50811 Line: {}, 50812 LOD: {}, 50813 Points: { threshold: 1 }, 50814 Sprite: {} 50815 }; 50816 50817 Object.defineProperties( this.params, { 50818 PointCloud: { 50819 get: function () { 50820 50821 console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' ); 50822 return this.Points; 50823 50824 } 50825 } 50826 } ); 50827 50828 } 50829 50830 function ascSort( a, b ) { 50831 50832 return a.distance - b.distance; 50833 50834 } 50835 50836 function intersectObject( object, raycaster, intersects, recursive ) { 50837 50838 if ( object.visible === false ) return; 50839 50840 object.raycast( raycaster, intersects ); 50841 50842 if ( recursive === true ) { 50843 50844 var children = object.children; 50845 50846 for ( var i = 0, l = children.length; i < l; i ++ ) { 50847 50848 intersectObject( children[ i ], raycaster, intersects, true ); 50849 50850 } 50851 50852 } 50853 50854 } 50855 50856 Object.assign( Raycaster.prototype, { 50857 50858 linePrecision: 1, 50859 50860 set: function ( origin, direction ) { 50861 50862 // direction is assumed to be normalized (for accurate distance calculations) 50863 50864 this.ray.set( origin, direction ); 50865 50866 }, 50867 50868 setFromCamera: function ( coords, camera ) { 50869 50870 if ( ( camera && camera.isPerspectiveCamera ) ) { 50871 50872 this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); 50873 this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); 50874 50875 } else if ( ( camera && camera.isOrthographicCamera ) ) { 50876 50877 this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera 50878 this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); 50879 50880 } else { 50881 50882 console.error( 'THREE.Raycaster: Unsupported camera type.' ); 50883 50884 } 50885 50886 }, 50887 50888 intersectObject: function ( object, recursive, optionalTarget ) { 50889 50890 var intersects = optionalTarget || []; 50891 50892 intersectObject( object, this, intersects, recursive ); 50893 50894 intersects.sort( ascSort ); 50895 50896 return intersects; 50897 50898 }, 50899 50900 intersectObjects: function ( objects, recursive, optionalTarget ) { 50901 50902 var intersects = optionalTarget || []; 50903 50904 if ( Array.isArray( objects ) === false ) { 50905 50906 console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); 50907 return intersects; 50908 50909 } 50910 50911 for ( var i = 0, l = objects.length; i < l; i ++ ) { 50912 50913 intersectObject( objects[ i ], this, intersects, recursive ); 50914 50915 } 50916 50917 intersects.sort( ascSort ); 50918 50919 return intersects; 50920 50921 } 50922 50923 } ); 50924 50925 /** 50926 * @author alteredq / http://alteredqualia.com/ 50927 */ 50928 50929 function Clock( autoStart ) { 50930 50931 this.autoStart = ( autoStart !== undefined ) ? autoStart : true; 50932 50933 this.startTime = 0; 50934 this.oldTime = 0; 50935 this.elapsedTime = 0; 50936 50937 this.running = false; 50938 50939 } 50940 50941 Object.assign( Clock.prototype, { 50942 50943 start: function () { 50944 50945 this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732 50946 50947 this.oldTime = this.startTime; 50948 this.elapsedTime = 0; 50949 this.running = true; 50950 50951 }, 50952 50953 stop: function () { 50954 50955 this.getElapsedTime(); 50956 this.running = false; 50957 this.autoStart = false; 50958 50959 }, 50960 50961 getElapsedTime: function () { 50962 50963 this.getDelta(); 50964 return this.elapsedTime; 50965 50966 }, 50967 50968 getDelta: function () { 50969 50970 var diff = 0; 50971 50972 if ( this.autoStart && ! this.running ) { 50973 50974 this.start(); 50975 return 0; 50976 50977 } 50978 50979 if ( this.running ) { 50980 50981 var newTime = ( typeof performance === 'undefined' ? Date : performance ).now(); 50982 50983 diff = ( newTime - this.oldTime ) / 1000; 50984 this.oldTime = newTime; 50985 50986 this.elapsedTime += diff; 50987 50988 } 50989 50990 return diff; 50991 50992 } 50993 50994 } ); 50995 50996 /** 50997 * @author bhouston / http://clara.io 50998 * @author WestLangley / http://github.com/WestLangley 50999 * 51000 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system 51001 * 51002 * The poles (phi) are at the positive and negative y axis. 51003 * The equator starts at positive z. 51004 */ 51005 51006 function Spherical( radius, phi, theta ) { 51007 51008 this.radius = ( radius !== undefined ) ? radius : 1.0; 51009 this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole 51010 this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere 51011 51012 return this; 51013 51014 } 51015 51016 Object.assign( Spherical.prototype, { 51017
vendor: 1,528 bytes, lines 51018-51094
51018 set: function ( radius, phi, theta ) { 51019 51020 this.radius = radius; 51021 this.phi = phi; 51022 this.theta = theta; 51023 51024 return this; 51025 51026 }, 51027 51028 clone: function () { 51029 51030 return new this.constructor().copy( this ); 51031 51032 }, 51033 51034 copy: function ( other ) { 51035 51036 this.radius = other.radius; 51037 this.phi = other.phi; 51038 this.theta = other.theta; 51039 51040 return this; 51041 51042 }, 51043 51044 // restrict phi to be betwee EPS and PI-EPS 51045 makeSafe: function () { 51046 51047 var EPS = 0.000001; 51048 this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) ); 51049 51050 return this; 51051 51052 }, 51053 51054 setFromVector3: function ( vec3 ) { 51055 51056 this.radius = vec3.length(); 51057 51058 if ( this.radius === 0 ) { 51059 51060 this.theta = 0; 51061 this.phi = 0; 51062 51063 } else { 51064 51065 this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis 51066 this.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle 51067 51068 } 51069 51070 return this; 51071 51072 } 51073 51074 } ); 51075 51076 /** 51077 * @author Mugen87 / https://github.com/Mugen87 51078 * 51079 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system 51080 * 51081 */ 51082 51083 function Cylindrical( radius, theta, y ) { 51084 51085 this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane 51086 this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis 51087 this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane 51088 51089 return this; 51090 51091 } 51092 51093 Object.assign( Cylindrical.prototype, { 51094
vendor: 4,357 bytes, lines 51095-51324
51095 set: function ( radius, theta, y ) { 51096 51097 this.radius = radius; 51098 this.theta = theta; 51099 this.y = y; 51100 51101 return this; 51102 51103 }, 51104 51105 clone: function () { 51106 51107 return new this.constructor().copy( this ); 51108 51109 }, 51110 51111 copy: function ( other ) { 51112 51113 this.radius = other.radius; 51114 this.theta = other.theta; 51115 this.y = other.y; 51116 51117 return this; 51118 51119 }, 51120 51121 setFromVector3: function ( vec3 ) { 51122 51123 this.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z ); 51124 this.theta = Math.atan2( vec3.x, vec3.z ); 51125 this.y = vec3.y; 51126 51127 return this; 51128 51129 } 51130 51131 } ); 51132 51133 /** 51134 * @author bhouston / http://clara.io 51135 */ 51136 51137 function Box2( min, max ) { 51138 51139 this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity ); 51140 this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity ); 51141 51142 } 51143 51144 Object.assign( Box2.prototype, { 51145 51146 set: function ( min, max ) { 51147 51148 this.min.copy( min ); 51149 this.max.copy( max ); 51150 51151 return this; 51152 51153 }, 51154 51155 setFromPoints: function ( points ) { 51156 51157 this.makeEmpty(); 51158 51159 for ( var i = 0, il = points.length; i < il; i ++ ) { 51160 51161 this.expandByPoint( points[ i ] ); 51162 51163 } 51164 51165 return this; 51166 51167 }, 51168 51169 setFromCenterAndSize: function () { 51170 51171 var v1 = new Vector2(); 51172 51173 return function setFromCenterAndSize( center, size ) { 51174 51175 var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); 51176 this.min.copy( center ).sub( halfSize ); 51177 this.max.copy( center ).add( halfSize ); 51178 51179 return this; 51180 51181 }; 51182 51183 }(), 51184 51185 clone: function () { 51186 51187 return new this.constructor().copy( this ); 51188 51189 }, 51190 51191 copy: function ( box ) { 51192 51193 this.min.copy( box.min ); 51194 this.max.copy( box.max ); 51195 51196 return this; 51197 51198 }, 51199 51200 makeEmpty: function () { 51201 51202 this.min.x = this.min.y = + Infinity; 51203 this.max.x = this.max.y = - Infinity; 51204 51205 return this; 51206 51207 }, 51208 51209 isEmpty: function () { 51210 51211 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes 51212 51213 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); 51214 51215 }, 51216 51217 getCenter: function ( target ) { 51218 51219 if ( target === undefined ) { 51220 51221 console.warn( 'THREE.Box2: .getCenter() target is now required' ); 51222 target = new Vector2(); 51223 51224 } 51225 51226 return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); 51227 51228 }, 51229 51230 getSize: function ( target ) { 51231 51232 if ( target === undefined ) { 51233 51234 console.warn( 'THREE.Box2: .getSize() target is now required' ); 51235 target = new Vector2(); 51236 51237 } 51238 51239 return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); 51240 51241 }, 51242 51243 expandByPoint: function ( point ) { 51244 51245 this.min.min( point ); 51246 this.max.max( point ); 51247 51248 return this; 51249 51250 }, 51251 51252 expandByVector: function ( vector ) { 51253 51254 this.min.sub( vector ); 51255 this.max.add( vector ); 51256 51257 return this; 51258 51259 }, 51260 51261 expandByScalar: function ( scalar ) { 51262 51263 this.min.addScalar( - scalar ); 51264 this.max.addScalar( scalar ); 51265 51266 return this; 51267 51268 }, 51269 51270 containsPoint: function ( point ) { 51271 51272 return point.x < this.min.x || point.x > this.max.x || 51273 point.y < this.min.y || point.y > this.max.y ? false : true; 51274 51275 }, 51276 51277 containsBox: function ( box ) { 51278 51279 return this.min.x <= box.min.x && box.max.x <= this.max.x && 51280 this.min.y <= box.min.y && box.max.y <= this.max.y; 51281 51282 }, 51283 51284 getParameter: function ( point, target ) { 51285 51286 // This can potentially have a divide by zero if the box 51287 // has a size dimension of 0. 51288 51289 if ( target === undefined ) { 51290 51291 console.warn( 'THREE.Box2: .getParameter() target is now required' ); 51292 target = new Vector2(); 51293 51294 } 51295 51296 return target.set( 51297 ( point.x - this.min.x ) / ( this.max.x - this.min.x ), 51298 ( point.y - this.min.y ) / ( this.max.y - this.min.y ) 51299 ); 51300 51301 }, 51302 51303 intersectsBox: function ( box ) { 51304 51305 // using 4 splitting planes to rule out intersections 51306 51307 return box.max.x < this.min.x || box.min.x > this.max.x || 51308 box.max.y < this.min.y || box.min.y > this.max.y ? false : true; 51309 51310 }, 51311 51312 clampPoint: function ( point, target ) { 51313 51314 if ( target === undefined ) { 51315 51316 console.warn( 'THREE.Box2: .clampPoint() target is now required' ); 51317 target = new Vector2(); 51318 51319 } 51320 51321 return target.copy( point ).clamp( this.min, this.max ); 51322 51323 }, 51324
51325 distanceToPoint: function () { 51326 51327 var v1 = new Vector2(); 51328 51329 return function distanceToPoint( point ) { 51330 51331 var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); 51332 return clampedPoint.sub( point ).length(); 51333 51334 }; 51335 51336 }(), 51337 51338 intersect: function ( box ) { 51339 51340 this.min.max( box.min ); 51341 this.max.min( box.max ); 51342 51343 return this; 51344 51345 }, 51346 51347 union: function ( box ) { 51348 51349 this.min.min( box.min ); 51350 this.max.max( box.max ); 51351 51352 return this; 51353 51354 }, 51355 51356 translate: function ( offset ) { 51357 51358 this.min.add( offset ); 51359 this.max.add( offset ); 51360 51361 return this; 51362 51363 }, 51364 51365 equals: function ( box ) { 51366 51367 return box.min.equals( this.min ) && box.max.equals( this.max ); 51368 51369 } 51370 51371 } ); 51372 51373 /** 51374 * @author alteredq / http://alteredqualia.com/ 51375 */ 51376 51377 function ImmediateRenderObject( material ) { 51378 51379 Object3D.call( this ); 51380 51381 this.material = material; 51382 this.render = function ( /* renderCallback */ ) {}; 51383 51384 } 51385 51386 ImmediateRenderObject.prototype = Object.create( Object3D.prototype ); 51387 ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; 51388 51389 ImmediateRenderObject.prototype.isImmediateRenderObject = true; 51390 51391 /** 51392 * @author mrdoob / http://mrdoob.com/ 51393 * @author WestLangley / http://github.com/WestLangley 51394 */ 51395 51396 function VertexNormalsHelper( object, size, hex, linewidth ) { 51397 51398 this.object = object; 51399 51400 this.size = ( size !== undefined ) ? size : 1; 51401 51402 var color = ( hex !== undefined ) ? hex : 0xff0000; 51403 51404 var width = ( linewidth !== undefined ) ? linewidth : 1; 51405 51406 // 51407 51408 var nNormals = 0; 51409 51410 var objGeometry = this.object.geometry; 51411 51412 if ( objGeometry && objGeometry.isGeometry ) { 51413 51414 nNormals = objGeometry.faces.length * 3; 51415 51416 } else if ( objGeometry && objGeometry.isBufferGeometry ) { 51417 51418 nNormals = objGeometry.attributes.normal.count; 51419 51420 } 51421 51422 // 51423 51424 var geometry = new BufferGeometry(); 51425 51426 var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); 51427 51428 geometry.addAttribute( 'position', positions ); 51429 51430 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); 51431 51432 // 51433 51434 this.matrixAutoUpdate = false; 51435 51436 this.update(); 51437 51438 } 51439 51440 VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); 51441 VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; 51442 51443 VertexNormalsHelper.prototype.update = ( function () { 51444 51445 var v1 = new Vector3(); 51446 var v2 = new Vector3(); 51447 var normalMatrix = new Matrix3(); 51448 51449 return function update() { 51450 51451 var keys = [ 'a', 'b', 'c' ]; 51452 51453 this.object.updateMatrixWorld( true ); 51454 51455 normalMatrix.getNormalMatrix( this.object.matrixWorld ); 51456 51457 var matrixWorld = this.object.matrixWorld; 51458 51459 var position = this.geometry.attributes.position; 51460 51461 // 51462 51463 var objGeometry = this.object.geometry; 51464 51465 if ( objGeometry && objGeometry.isGeometry ) { 51466 51467 var vertices = objGeometry.vertices; 51468 51469 var faces = objGeometry.faces; 51470 51471 var idx = 0; 51472 51473 for ( var i = 0, l = faces.length; i < l; i ++ ) { 51474 51475 var face = faces[ i ]; 51476 51477 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { 51478 51479 var vertex = vertices[ face[ keys[ j ] ] ]; 51480 51481 var normal = face.vertexNormals[ j ]; 51482 51483 v1.copy( vertex ).applyMatrix4( matrixWorld ); 51484 51485 v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); 51486 51487 position.setXYZ( idx, v1.x, v1.y, v1.z ); 51488 51489 idx = idx + 1; 51490 51491 position.setXYZ( idx, v2.x, v2.y, v2.z ); 51492 51493 idx = idx + 1; 51494 51495 } 51496 51497 } 51498 51499 } else if ( objGeometry && objGeometry.isBufferGeometry ) { 51500 51501 var objPos = objGeometry.attributes.position; 51502 51503 var objNorm = objGeometry.attributes.normal; 51504 51505 var idx = 0; 51506 51507 // for simplicity, ignore index and drawcalls, and render every normal 51508 51509 for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { 51510 51511 v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); 51512 51513 v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); 51514 51515 v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); 51516 51517 position.setXYZ( idx, v1.x, v1.y, v1.z ); 51518 51519 idx = idx + 1; 51520 51521 position.setXYZ( idx, v2.x, v2.y, v2.z ); 51522 51523 idx = idx + 1; 51524 51525 } 51526 51527 } 51528 51529 position.needsUpdate = true; 51530 51531 }; 51532 51533 }() ); 51534 51535 /** 51536 * @author alteredq / http://alteredqualia.com/ 51537 * @author mrdoob / http://mrdoob.com/ 51538 * @author WestLangley / http://github.com/WestLangley 51539 */ 51540 51541 function SpotLightHelper( light, color ) { 51542 51543 Object3D.call( this ); 51544 51545 this.light = light; 51546 this.light.updateMatrixWorld(); 51547 51548 this.matrix = light.matrixWorld; 51549 this.matrixAutoUpdate = false;
vendor: 5,008 bytes, lines 51550-51764
51550 51551 this.color = color; 51552 51553 var geometry = new BufferGeometry(); 51554 51555 var positions = [ 51556 0, 0, 0, 0, 0, 1, 51557 0, 0, 0, 1, 0, 1, 51558 0, 0, 0, - 1, 0, 1, 51559 0, 0, 0, 0, 1, 1, 51560 0, 0, 0, 0, - 1, 1 51561 ]; 51562 51563 for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { 51564 51565 var p1 = ( i / l ) * Math.PI * 2; 51566 var p2 = ( j / l ) * Math.PI * 2; 51567 51568 positions.push( 51569 Math.cos( p1 ), Math.sin( p1 ), 1, 51570 Math.cos( p2 ), Math.sin( p2 ), 1 51571 ); 51572 51573 } 51574 51575 geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 51576 51577 var material = new LineBasicMaterial( { fog: false } ); 51578 51579 this.cone = new LineSegments( geometry, material ); 51580 this.add( this.cone ); 51581 51582 this.update(); 51583 51584 } 51585 51586 SpotLightHelper.prototype = Object.create( Object3D.prototype ); 51587 SpotLightHelper.prototype.constructor = SpotLightHelper; 51588 51589 SpotLightHelper.prototype.dispose = function () { 51590 51591 this.cone.geometry.dispose(); 51592 this.cone.material.dispose(); 51593 51594 }; 51595 51596 SpotLightHelper.prototype.update = function () { 51597 51598 var vector = new Vector3(); 51599 var vector2 = new Vector3(); 51600 51601 return function update() { 51602 51603 this.light.updateMatrixWorld(); 51604 51605 var coneLength = this.light.distance ? this.light.distance : 1000; 51606 var coneWidth = coneLength * Math.tan( this.light.angle ); 51607 51608 this.cone.scale.set( coneWidth, coneWidth, coneLength ); 51609 51610 vector.setFromMatrixPosition( this.light.matrixWorld ); 51611 vector2.setFromMatrixPosition( this.light.target.matrixWorld ); 51612 51613 this.cone.lookAt( vector2.sub( vector ) ); 51614 51615 if ( this.color !== undefined ) { 51616 51617 this.cone.material.color.set( this.color ); 51618 51619 } else { 51620 51621 this.cone.material.color.copy( this.light.color ); 51622 51623 } 51624 51625 }; 51626 51627 }(); 51628 51629 /** 51630 * @author Sean Griffin / http://twitter.com/sgrif 51631 * @author Michael Guerrero / http://realitymeltdown.com 51632 * @author mrdoob / http://mrdoob.com/ 51633 * @author ikerr / http://verold.com 51634 * @author Mugen87 / https://github.com/Mugen87 51635 */ 51636 51637 function getBoneList( object ) { 51638 51639 var boneList = []; 51640 51641 if ( object && object.isBone ) { 51642 51643 boneList.push( object ); 51644 51645 } 51646 51647 for ( var i = 0; i < object.children.length; i ++ ) { 51648 51649 boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); 51650 51651 } 51652 51653 return boneList; 51654 51655 } 51656 51657 function SkeletonHelper( object ) { 51658 51659 var bones = getBoneList( object ); 51660 51661 var geometry = new BufferGeometry(); 51662 51663 var vertices = []; 51664 var colors = []; 51665 51666 var color1 = new Color( 0, 0, 1 ); 51667 var color2 = new Color( 0, 1, 0 ); 51668 51669 for ( var i = 0; i < bones.length; i ++ ) { 51670 51671 var bone = bones[ i ]; 51672 51673 if ( bone.parent && bone.parent.isBone ) { 51674 51675 vertices.push( 0, 0, 0 ); 51676 vertices.push( 0, 0, 0 ); 51677 colors.push( color1.r, color1.g, color1.b ); 51678 colors.push( color2.r, color2.g, color2.b ); 51679 51680 } 51681 51682 } 51683 51684 geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 51685 geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 51686 51687 var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } ); 51688 51689 LineSegments.call( this, geometry, material ); 51690 51691 this.root = object; 51692 this.bones = bones; 51693 51694 this.matrix = object.matrixWorld; 51695 this.matrixAutoUpdate = false; 51696 51697 } 51698 51699 SkeletonHelper.prototype = Object.create( LineSegments.prototype ); 51700 SkeletonHelper.prototype.constructor = SkeletonHelper; 51701 51702 SkeletonHelper.prototype.updateMatrixWorld = function () { 51703 51704 var vector = new Vector3(); 51705 51706 var boneMatrix = new Matrix4(); 51707 var matrixWorldInv = new Matrix4(); 51708 51709 return function updateMatrixWorld( force ) { 51710 51711 var bones = this.bones; 51712 51713 var geometry = this.geometry; 51714 var position = geometry.getAttribute( 'position' ); 51715 51716 matrixWorldInv.getInverse( this.root.matrixWorld ); 51717 51718 for ( var i = 0, j = 0; i < bones.length; i ++ ) { 51719 51720 var bone = bones[ i ]; 51721 51722 if ( bone.parent && bone.parent.isBone ) { 51723 51724 boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld ); 51725 vector.setFromMatrixPosition( boneMatrix ); 51726 position.setXYZ( j, vector.x, vector.y, vector.z ); 51727 51728 boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld ); 51729 vector.setFromMatrixPosition( boneMatrix ); 51730 position.setXYZ( j + 1, vector.x, vector.y, vector.z ); 51731 51732 j += 2; 51733 51734 } 51735 51736 } 51737 51738 geometry.getAttribute( 'position' ).needsUpdate = true; 51739 51740 Object3D.prototype.updateMatrixWorld.call( this, force ); 51741 51742 }; 51743 51744 }(); 51745 51746 /** 51747 * @author alteredq / http://alteredqualia.com/ 51748 * @author mrdoob / http://mrdoob.com/ 51749 */ 51750 51751 function PointLightHelper( light, sphereSize, color ) { 51752 51753 this.light = light; 51754 this.light.updateMatrixWorld(); 51755 51756 this.color = color; 51757 51758 var geometry = new SphereBufferGeometry( sphereSize, 4, 2 ); 51759 var material = new MeshBasicMaterial( { wireframe: true, fog: false } ); 51760 51761 Mesh.call( this, geometry, material ); 51762 51763 this.matrix = this.light.matrixWorld; 51764 this.matrixAutoUpdate = false;
51765 51766 this.update(); 51767 51768 51769 /* 51770 var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); 51771 var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); 51772 51773 this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); 51774 this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); 51775 51776 var d = light.distance; 51777 51778 if ( d === 0.0 ) { 51779 51780 this.lightDistance.visible = false; 51781 51782 } else { 51783 51784 this.lightDistance.scale.set( d, d, d ); 51785 51786 } 51787 51788 this.add( this.lightDistance ); 51789 */ 51790 51791 } 51792 51793 PointLightHelper.prototype = Object.create( Mesh.prototype ); 51794 PointLightHelper.prototype.constructor = PointLightHelper; 51795 51796 PointLightHelper.prototype.dispose = function () { 51797 51798 this.geometry.dispose(); 51799 this.material.dispose(); 51800 51801 }; 51802 51803 PointLightHelper.prototype.update = function () { 51804 51805 if ( this.color !== undefined ) { 51806 51807 this.material.color.set( this.color ); 51808 51809 } else { 51810 51811 this.material.color.copy( this.light.color ); 51812 51813 } 51814 51815 /* 51816 var d = this.light.distance; 51817 51818 if ( d === 0.0 ) { 51819 51820 this.lightDistance.visible = false; 51821 51822 } else { 51823 51824 this.lightDistance.visible = true; 51825 this.lightDistance.scale.set( d, d, d ); 51826 51827 } 51828 */ 51829 51830 }; 51831 51832 /** 51833 * @author abelnation / http://github.com/abelnation 51834 * @author Mugen87 / http://github.com/Mugen87 51835 * @author WestLangley / http://github.com/WestLangley 51836 */ 51837 51838 function RectAreaLightHelper( light, color ) { 51839 51840 Object3D.call( this ); 51841 51842 this.light = light; 51843 this.light.updateMatrixWorld(); 51844 51845 this.matrix = light.matrixWorld; 51846 this.matrixAutoUpdate = false; 51847 51848 this.color = color; 51849 51850 var material = new LineBasicMaterial( { fog: false } ); 51851 51852 var geometry = new BufferGeometry(); 51853 51854 geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) ); 51855 51856 this.line = new Line( geometry, material ); 51857 this.add( this.line ); 51858 51859 51860 this.update(); 51861 51862 } 51863 51864 RectAreaLightHelper.prototype = Object.create( Object3D.prototype ); 51865 RectAreaLightHelper.prototype.constructor = RectAreaLightHelper; 51866 51867 RectAreaLightHelper.prototype.dispose = function () { 51868 51869 this.children[ 0 ].geometry.dispose(); 51870 this.children[ 0 ].material.dispose(); 51871 51872 }; 51873 51874 RectAreaLightHelper.prototype.update = function () { 51875 51876 // calculate new dimensions of the helper 51877 51878 var hx = this.light.width * 0.5; 51879 var hy = this.light.height * 0.5; 51880 51881 var position = this.line.geometry.attributes.position; 51882 var array = position.array; 51883 51884 // update vertices 51885 51886 array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0; 51887 array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0; 51888 array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0; 51889 array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0; 51890 array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0; 51891 51892 position.needsUpdate = true; 51893 51894 if ( this.color !== undefined ) { 51895 51896 this.line.material.color.set( this.color ); 51897 51898 } else { 51899 51900 this.line.material.color.copy( this.light.color ); 51901 51902 } 51903 51904 }; 51905 51906 /** 51907 * @author alteredq / http://alteredqualia.com/ 51908 * @author mrdoob / http://mrdoob.com/ 51909 * @author Mugen87 / https://github.com/Mugen87 51910 */ 51911 51912 function HemisphereLightHelper( light, size, color ) { 51913 51914 Object3D.call( this ); 51915 51916 this.light = light; 51917 this.light.updateMatrixWorld(); 51918 51919 this.matrix = light.matrixWorld; 51920 this.matrixAutoUpdate = false; 51921 51922 this.color = color; 51923 51924 var geometry = new OctahedronBufferGeometry( size ); 51925 geometry.rotateY( Math.PI * 0.5 ); 51926 51927 this.material = new MeshBasicMaterial( { wireframe: true, fog: false } ); 51928 if ( this.color === undefined ) this.material.vertexColors = VertexColors; 51929 51930 var position = geometry.getAttribute( 'position' ); 51931 var colors = new Float32Array( position.count * 3 ); 51932 51933 geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) ); 51934 51935 this.add( new Mesh( geometry, this.material ) ); 51936 51937 this.update(); 51938 51939 } 51940 51941 HemisphereLightHelper.prototype = Object.create( Object3D.prototype ); 51942 HemisphereLightHelper.prototype.constructor = HemisphereLightHelper; 51943 51944 HemisphereLightHelper.prototype.dispose = function () { 51945 51946 this.children[ 0 ].geometry.dispose(); 51947 this.children[ 0 ].material.dispose(); 51948 51949 }; 51950 51951 HemisphereLightHelper.prototype.update = function () { 51952 51953 var vector = new Vector3(); 51954 51955 var color1 = new Color(); 51956 var color2 = new Color(); 51957
vendor: 4,151 bytes, lines 51958-52128
51958 return function update() { 51959 51960 var mesh = this.children[ 0 ]; 51961 51962 if ( this.color !== undefined ) { 51963 51964 this.material.color.set( this.color ); 51965 51966 } else { 51967 51968 var colors = mesh.geometry.getAttribute( 'color' ); 51969 51970 color1.copy( this.light.color ); 51971 color2.copy( this.light.groundColor ); 51972 51973 for ( var i = 0, l = colors.count; i < l; i ++ ) { 51974 51975 var color = ( i < ( l / 2 ) ) ? color1 : color2; 51976 51977 colors.setXYZ( i, color.r, color.g, color.b ); 51978 51979 } 51980 51981 colors.needsUpdate = true; 51982 51983 } 51984 51985 mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); 51986 51987 }; 51988 51989 }(); 51990 51991 /** 51992 * @author mrdoob / http://mrdoob.com/ 51993 */ 51994 51995 function GridHelper( size, divisions, color1, color2 ) { 51996 51997 size = size || 10; 51998 divisions = divisions || 10; 51999 color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); 52000 color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); 52001 52002 var center = divisions / 2; 52003 var step = size / divisions; 52004 var halfSize = size / 2; 52005 52006 var vertices = [], colors = []; 52007 52008 for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) { 52009 52010 vertices.push( - halfSize, 0, k, halfSize, 0, k ); 52011 vertices.push( k, 0, - halfSize, k, 0, halfSize ); 52012 52013 var color = i === center ? color1 : color2; 52014 52015 color.toArray( colors, j ); j += 3; 52016 color.toArray( colors, j ); j += 3; 52017 color.toArray( colors, j ); j += 3; 52018 color.toArray( colors, j ); j += 3; 52019 52020 } 52021 52022 var geometry = new BufferGeometry(); 52023 geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 52024 geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 52025 52026 var material = new LineBasicMaterial( { vertexColors: VertexColors } ); 52027 52028 LineSegments.call( this, geometry, material ); 52029 52030 } 52031 52032 GridHelper.prototype = Object.create( LineSegments.prototype ); 52033 GridHelper.prototype.constructor = GridHelper; 52034 52035 /** 52036 * @author mrdoob / http://mrdoob.com/ 52037 * @author Mugen87 / http://github.com/Mugen87 52038 * @author Hectate / http://www.github.com/Hectate 52039 */ 52040 52041 function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) { 52042 52043 radius = radius || 10; 52044 radials = radials || 16; 52045 circles = circles || 8; 52046 divisions = divisions || 64; 52047 color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); 52048 color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); 52049 52050 var vertices = []; 52051 var colors = []; 52052 52053 var x, z; 52054 var v, i, j, r, color; 52055 52056 // create the radials 52057 52058 for ( i = 0; i <= radials; i ++ ) { 52059 52060 v = ( i / radials ) * ( Math.PI * 2 ); 52061 52062 x = Math.sin( v ) * radius; 52063 z = Math.cos( v ) * radius; 52064 52065 vertices.push( 0, 0, 0 ); 52066 vertices.push( x, 0, z ); 52067 52068 color = ( i & 1 ) ? color1 : color2; 52069 52070 colors.push( color.r, color.g, color.b ); 52071 colors.push( color.r, color.g, color.b ); 52072 52073 } 52074 52075 // create the circles 52076 52077 for ( i = 0; i <= circles; i ++ ) { 52078 52079 color = ( i & 1 ) ? color1 : color2; 52080 52081 r = radius - ( radius / circles * i ); 52082 52083 for ( j = 0; j < divisions; j ++ ) { 52084 52085 // first vertex 52086 52087 v = ( j / divisions ) * ( Math.PI * 2 ); 52088 52089 x = Math.sin( v ) * r; 52090 z = Math.cos( v ) * r; 52091 52092 vertices.push( x, 0, z ); 52093 colors.push( color.r, color.g, color.b ); 52094 52095 // second vertex 52096 52097 v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); 52098 52099 x = Math.sin( v ) * r; 52100 z = Math.cos( v ) * r; 52101 52102 vertices.push( x, 0, z ); 52103 colors.push( color.r, color.g, color.b ); 52104 52105 } 52106 52107 } 52108 52109 var geometry = new BufferGeometry(); 52110 geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 52111 geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 52112 52113 var material = new LineBasicMaterial( { vertexColors: VertexColors } ); 52114 52115 LineSegments.call( this, geometry, material ); 52116 52117 } 52118 52119 PolarGridHelper.prototype = Object.create( LineSegments.prototype ); 52120 PolarGridHelper.prototype.constructor = PolarGridHelper; 52121 52122 /** 52123 * @author mrdoob / http://mrdoob.com/ 52124 * @author WestLangley / http://github.com/WestLangley 52125 */ 52126 52127 function FaceNormalsHelper( object, size, hex, linewidth ) { 52128
52129 // FaceNormalsHelper only supports THREE.Geometry 52130 52131 this.object = object; 52132 52133 this.size = ( size !== undefined ) ? size : 1; 52134 52135 var color = ( hex !== undefined ) ? hex : 0xffff00; 52136 52137 var width = ( linewidth !== undefined ) ? linewidth : 1; 52138 52139 // 52140 52141 var nNormals = 0; 52142 52143 var objGeometry = this.object.geometry; 52144 52145 if ( objGeometry && objGeometry.isGeometry ) { 52146 52147 nNormals = objGeometry.faces.length; 52148 52149 } else { 52150 52151 console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' ); 52152 52153 } 52154 52155 // 52156 52157 var geometry = new BufferGeometry(); 52158 52159 var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); 52160 52161 geometry.addAttribute( 'position', positions ); 52162 52163 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); 52164 52165 // 52166 52167 this.matrixAutoUpdate = false; 52168 this.update(); 52169 52170 } 52171 52172 FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); 52173 FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; 52174 52175 FaceNormalsHelper.prototype.update = ( function () { 52176 52177 var v1 = new Vector3(); 52178 var v2 = new Vector3(); 52179 var normalMatrix = new Matrix3(); 52180 52181 return function update() { 52182 52183 this.object.updateMatrixWorld( true ); 52184 52185 normalMatrix.getNormalMatrix( this.object.matrixWorld ); 52186 52187 var matrixWorld = this.object.matrixWorld; 52188 52189 var position = this.geometry.attributes.position; 52190 52191 // 52192 52193 var objGeometry = this.object.geometry; 52194 52195 var vertices = objGeometry.vertices; 52196 52197 var faces = objGeometry.faces; 52198 52199 var idx = 0; 52200 52201 for ( var i = 0, l = faces.length; i < l; i ++ ) { 52202 52203 var face = faces[ i ]; 52204 52205 var normal = face.normal; 52206 52207 v1.copy( vertices[ face.a ] ) 52208 .add( vertices[ face.b ] ) 52209 .add( vertices[ face.c ] ) 52210 .divideScalar( 3 ) 52211 .applyMatrix4( matrixWorld ); 52212 52213 v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); 52214 52215 position.setXYZ( idx, v1.x, v1.y, v1.z ); 52216 52217 idx = idx + 1; 52218 52219 position.setXYZ( idx, v2.x, v2.y, v2.z ); 52220 52221 idx = idx + 1; 52222 52223 } 52224 52225 position.needsUpdate = true; 52226 52227 }; 52228 52229 }() ); 52230 52231 /** 52232 * @author alteredq / http://alteredqualia.com/ 52233 * @author mrdoob / http://mrdoob.com/ 52234 * @author WestLangley / http://github.com/WestLangley 52235 */ 52236 52237 function DirectionalLightHelper( light, size, color ) { 52238 52239 Object3D.call( this ); 52240 52241 this.light = light; 52242 this.light.updateMatrixWorld(); 52243 52244 this.matrix = light.matrixWorld; 52245 this.matrixAutoUpdate = false; 52246 52247 this.color = color; 52248 52249 if ( size === undefined ) size = 1; 52250 52251 var geometry = new BufferGeometry(); 52252 geometry.addAttribute( 'position', new Float32BufferAttribute( [ 52253 - size, size, 0, 52254 size, size, 0, 52255 size, - size, 0, 52256 - size, - size, 0, 52257 - size, size, 0 52258 ], 3 ) ); 52259 52260 var material = new LineBasicMaterial( { fog: false } ); 52261 52262 this.lightPlane = new Line( geometry, material ); 52263 this.add( this.lightPlane ); 52264 52265 geometry = new BufferGeometry(); 52266 geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); 52267 52268 this.targetLine = new Line( geometry, material ); 52269 this.add( this.targetLine ); 52270 52271 this.update(); 52272 52273 } 52274 52275 DirectionalLightHelper.prototype = Object.create( Object3D.prototype ); 52276 DirectionalLightHelper.prototype.constructor = DirectionalLightHelper; 52277 52278 DirectionalLightHelper.prototype.dispose = function () { 52279 52280 this.lightPlane.geometry.dispose(); 52281 this.lightPlane.material.dispose(); 52282 this.targetLine.geometry.dispose(); 52283 this.targetLine.material.dispose(); 52284 52285 }; 52286 52287 DirectionalLightHelper.prototype.update = function () { 52288 52289 var v1 = new Vector3(); 52290 var v2 = new Vector3(); 52291 var v3 = new Vector3(); 52292 52293 return function update() { 52294 52295 v1.setFromMatrixPosition( this.light.matrixWorld ); 52296 v2.setFromMatrixPosition( this.light.target.matrixWorld ); 52297 v3.subVectors( v2, v1 ); 52298 52299 this.lightPlane.lookAt( v3 ); 52300 52301 if ( this.color !== undefined ) { 52302 52303 this.lightPlane.material.color.set( this.color ); 52304 this.targetLine.material.color.set( this.color ); 52305 52306 } else { 52307
52308 this.lightPlane.material.color.copy( this.light.color ); 52309 this.targetLine.material.color.copy( this.light.color ); 52310 52311 } 52312 52313 this.targetLine.lookAt( v3 ); 52314 this.targetLine.scale.z = v3.length(); 52315 52316 }; 52317 52318 }(); 52319 52320 /** 52321 * @author alteredq / http://alteredqualia.com/ 52322 * @author Mugen87 / https://github.com/Mugen87 52323 * 52324 * - shows frustum, line of sight and up of the camera 52325 * - suitable for fast updates 52326 * - based on frustum visualization in lightgl.js shadowmap example 52327 * http://evanw.github.com/lightgl.js/tests/shadowmap.html 52328 */ 52329 52330 function CameraHelper( camera ) { 52331 52332 var geometry = new BufferGeometry(); 52333 var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); 52334 52335 var vertices = []; 52336 var colors = []; 52337 52338 var pointMap = {}; 52339 52340 // colors 52341 52342 var colorFrustum = new Color( 0xffaa00 ); 52343 var colorCone = new Color( 0xff0000 ); 52344 var colorUp = new Color( 0x00aaff ); 52345 var colorTarget = new Color( 0xffffff ); 52346 var colorCross = new Color( 0x333333 ); 52347 52348 // near 52349 52350 addLine( 'n1', 'n2', colorFrustum ); 52351 addLine( 'n2', 'n4', colorFrustum ); 52352 addLine( 'n4', 'n3', colorFrustum ); 52353 addLine( 'n3', 'n1', colorFrustum ); 52354 52355 // far 52356 52357 addLine( 'f1', 'f2', colorFrustum ); 52358 addLine( 'f2', 'f4', colorFrustum ); 52359 addLine( 'f4', 'f3', colorFrustum ); 52360 addLine( 'f3', 'f1', colorFrustum ); 52361 52362 // sides 52363 52364 addLine( 'n1', 'f1', colorFrustum ); 52365 addLine( 'n2', 'f2', colorFrustum ); 52366 addLine( 'n3', 'f3', colorFrustum ); 52367 addLine( 'n4', 'f4', colorFrustum ); 52368 52369 // cone 52370 52371 addLine( 'p', 'n1', colorCone ); 52372 addLine( 'p', 'n2', colorCone ); 52373 addLine( 'p', 'n3', colorCone ); 52374 addLine( 'p', 'n4', colorCone ); 52375 52376 // up 52377 52378 addLine( 'u1', 'u2', colorUp ); 52379 addLine( 'u2', 'u3', colorUp ); 52380 addLine( 'u3', 'u1', colorUp ); 52381 52382 // target 52383 52384 addLine( 'c', 't', colorTarget ); 52385 addLine( 'p', 'c', colorCross ); 52386 52387 // cross 52388 52389 addLine( 'cn1', 'cn2', colorCross ); 52390 addLine( 'cn3', 'cn4', colorCross ); 52391 52392 addLine( 'cf1', 'cf2', colorCross ); 52393 addLine( 'cf3', 'cf4', colorCross ); 52394 52395 function addLine( a, b, color ) { 52396 52397 addPoint( a, color ); 52398 addPoint( b, color ); 52399 52400 } 52401 52402 function addPoint( id, color ) { 52403 52404 vertices.push( 0, 0, 0 ); 52405 colors.push( color.r, color.g, color.b ); 52406 52407 if ( pointMap[ id ] === undefined ) { 52408 52409 pointMap[ id ] = []; 52410 52411 } 52412 52413 pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); 52414 52415 } 52416 52417 geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 52418 geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 52419 52420 LineSegments.call( this, geometry, material ); 52421 52422 this.camera = camera; 52423 if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); 52424 52425 this.matrix = camera.matrixWorld; 52426 this.matrixAutoUpdate = false; 52427 52428 this.pointMap = pointMap; 52429 52430 this.update(); 52431 52432 } 52433 52434 CameraHelper.prototype = Object.create( LineSegments.prototype ); 52435 CameraHelper.prototype.constructor = CameraHelper; 52436 52437 CameraHelper.prototype.update = function () { 52438 52439 var geometry, pointMap; 52440 52441 var vector = new Vector3(); 52442 var camera = new Camera(); 52443 52444 function setPoint( point, x, y, z ) { 52445 52446 vector.set( x, y, z ).unproject( camera ); 52447 52448 var points = pointMap[ point ]; 52449 52450 if ( points !== undefined ) { 52451 52452 var position = geometry.getAttribute( 'position' ); 52453 52454 for ( var i = 0, l = points.length; i < l; i ++ ) { 52455 52456 position.setXYZ( points[ i ], vector.x, vector.y, vector.z ); 52457 52458 } 52459 52460 } 52461 52462 } 52463 52464 return function update() { 52465 52466 geometry = this.geometry; 52467 pointMap = this.pointMap; 52468 52469 var w = 1, h = 1; 52470 52471 // we need just camera projection matrix 52472 // world matrix must be identity 52473 52474 camera.projectionMatrix.copy( this.camera.projectionMatrix ); 52475 52476 // center / target 52477 52478 setPoint( 'c', 0, 0, - 1 ); 52479 setPoint( 't', 0, 0, 1 ); 52480 52481 // near 52482 52483 setPoint( 'n1', - w, - h, - 1 ); 52484 setPoint( 'n2', w, - h, - 1 ); 52485 setPoint( 'n3', - w, h, - 1 ); 52486 setPoint( 'n4', w, h, - 1 ); 52487 52488 // far 52489 52490 setPoint( 'f1', - w, - h, 1 ); 52491 setPoint( 'f2', w, - h, 1 ); 52492 setPoint( 'f3', - w, h, 1 ); 52493 setPoint( 'f4', w, h, 1 ); 52494 52495 // up 52496 52497 setPoint( 'u1', w * 0.7, h * 1.1, - 1 ); 52498 setPoint( 'u2', - w * 0.7, h * 1.1, - 1 ); 52499 setPoint( 'u3', 0, h * 2, - 1 ); 52500 52501 // cross 52502 52503 setPoint( 'cf1', - w, 0, 1 ); 52504 setPoint( 'cf2', w, 0, 1 ); 52505 setPoint( 'cf3', 0, - h, 1 ); 52506 setPoint( 'cf4', 0, h, 1 ); 52507 52508 setPoint( 'cn1', - w, 0, - 1 ); 52509 setPoint( 'cn2', w, 0, - 1 ); 52510 setPoint( 'cn3', 0, - h, - 1 ); 52511 setPoint( 'cn4', 0, h, - 1 ); 52512 52513 geometry.getAttribute( 'position' ).needsUpdate = true; 52514 52515 }; 52516 52517 }(); 52518 52519 /** 52520 * @author mrdoob / http://mrdoob.com/ 52521 * @author Mugen87 / http://github.com/Mugen87 52522 */ 52523 52524 function BoxHelper( object, color ) { 52525 52526 this.object = object; 52527 52528 if ( color === undefined ) color = 0xffff00; 52529 52530 var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); 52531 var positions = new Float32Array( 8 * 3 ); 52532 52533 var geometry = new BufferGeometry(); 52534 geometry.setIndex( new BufferAttribute( indices, 1 ) ); 52535 geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); 52536 52537 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); 52538 52539 this.matrixAutoUpdate = false;
vendor: 5,749 bytes, lines 52540-52758
52540 52541 this.update(); 52542 52543 } 52544 52545 BoxHelper.prototype = Object.create( LineSegments.prototype ); 52546 BoxHelper.prototype.constructor = BoxHelper; 52547 52548 BoxHelper.prototype.update = ( function () { 52549 52550 var box = new Box3(); 52551 52552 return function update( object ) { 52553 52554 if ( object !== undefined ) { 52555 52556 console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); 52557 52558 } 52559 52560 if ( this.object !== undefined ) { 52561 52562 box.setFromObject( this.object ); 52563 52564 } 52565 52566 if ( box.isEmpty() ) return; 52567 52568 var min = box.min; 52569 var max = box.max; 52570 52571 /* 52572 5____4 52573 1/___0/| 52574 | 6__|_7 52575 2/___3/ 52576 52577 0: max.x, max.y, max.z 52578 1: min.x, max.y, max.z 52579 2: min.x, min.y, max.z 52580 3: max.x, min.y, max.z 52581 4: max.x, max.y, min.z 52582 5: min.x, max.y, min.z 52583 6: min.x, min.y, min.z 52584 7: max.x, min.y, min.z 52585 */ 52586 52587 var position = this.geometry.attributes.position; 52588 var array = position.array; 52589 52590 array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; 52591 array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; 52592 array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; 52593 array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; 52594 array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; 52595 array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; 52596 array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; 52597 array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; 52598 52599 position.needsUpdate = true; 52600 52601 this.geometry.computeBoundingSphere(); 52602 52603 }; 52604 52605 } )(); 52606 52607 BoxHelper.prototype.setFromObject = function ( object ) { 52608 52609 this.object = object; 52610 this.update(); 52611 52612 return this; 52613 52614 }; 52615 52616 /** 52617 * @author WestLangley / http://github.com/WestLangley 52618 */ 52619 52620 function Box3Helper( box, hex ) { 52621 52622 this.type = 'Box3Helper'; 52623 52624 this.box = box; 52625 52626 var color = ( hex !== undefined ) ? hex : 0xffff00; 52627 52628 var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); 52629 52630 var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ]; 52631 52632 var geometry = new BufferGeometry(); 52633 52634 geometry.setIndex( new BufferAttribute( indices, 1 ) ); 52635 52636 geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 52637 52638 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); 52639 52640 this.geometry.computeBoundingSphere(); 52641 52642 } 52643 52644 Box3Helper.prototype = Object.create( LineSegments.prototype ); 52645 Box3Helper.prototype.constructor = Box3Helper; 52646 52647 Box3Helper.prototype.updateMatrixWorld = function ( force ) { 52648 52649 var box = this.box; 52650 52651 if ( box.isEmpty() ) return; 52652 52653 box.getCenter( this.position ); 52654 52655 box.getSize( this.scale ); 52656 52657 this.scale.multiplyScalar( 0.5 ); 52658 52659 Object3D.prototype.updateMatrixWorld.call( this, force ); 52660 52661 }; 52662 52663 /** 52664 * @author WestLangley / http://github.com/WestLangley 52665 */ 52666 52667 function PlaneHelper( plane, size, hex ) { 52668 52669 this.type = 'PlaneHelper'; 52670 52671 this.plane = plane; 52672 52673 this.size = ( size === undefined ) ? 1 : size; 52674 52675 var color = ( hex !== undefined ) ? hex : 0xffff00; 52676 52677 var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; 52678 52679 var geometry = new BufferGeometry(); 52680 geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); 52681 geometry.computeBoundingSphere(); 52682 52683 Line.call( this, geometry, new LineBasicMaterial( { color: color } ) ); 52684 52685 // 52686 52687 var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; 52688 52689 var geometry2 = new BufferGeometry(); 52690 geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); 52691 geometry2.computeBoundingSphere(); 52692 52693 this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) ); 52694 52695 } 52696 52697 PlaneHelper.prototype = Object.create( Line.prototype ); 52698 PlaneHelper.prototype.constructor = PlaneHelper; 52699 52700 PlaneHelper.prototype.updateMatrixWorld = function ( force ) { 52701 52702 var scale = - this.plane.constant; 52703 52704 if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter 52705 52706 this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); 52707 52708 this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here 52709 52710 this.lookAt( this.plane.normal ); 52711 52712 Object3D.prototype.updateMatrixWorld.call( this, force ); 52713 52714 }; 52715 52716 /** 52717 * @author WestLangley / http://github.com/WestLangley 52718 * @author zz85 / http://github.com/zz85 52719 * @author bhouston / http://clara.io 52720 * 52721 * Creates an arrow for visualizing directions 52722 * 52723 * Parameters: 52724 * dir - Vector3 52725 * origin - Vector3 52726 * length - Number 52727 * color - color in hex value 52728 * headLength - Number 52729 * headWidth - Number 52730 */ 52731 52732 var lineGeometry, coneGeometry; 52733 52734 function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { 52735 52736 // dir is assumed to be normalized 52737 52738 Object3D.call( this ); 52739 52740 if ( color === undefined ) color = 0xffff00; 52741 if ( length === undefined ) length = 1; 52742 if ( headLength === undefined ) headLength = 0.2 * length; 52743 if ( headWidth === undefined ) headWidth = 0.2 * headLength; 52744 52745 if ( lineGeometry === undefined ) { 52746 52747 lineGeometry = new BufferGeometry(); 52748 lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); 52749 52750 coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); 52751 coneGeometry.translate( 0, - 0.5, 0 ); 52752 52753 } 52754 52755 this.position.copy( origin ); 52756 52757 this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) ); 52758 this.line.matrixAutoUpdate = false;
52759 this.add( this.line ); 52760 52761 this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) ); 52762 this.cone.matrixAutoUpdate = false; 52763 this.add( this.cone ); 52764 52765 this.setDirection( dir ); 52766 this.setLength( length, headLength, headWidth ); 52767 52768 } 52769 52770 ArrowHelper.prototype = Object.create( Object3D.prototype ); 52771 ArrowHelper.prototype.constructor = ArrowHelper; 52772 52773 ArrowHelper.prototype.setDirection = ( function () { 52774 52775 var axis = new Vector3(); 52776 var radians; 52777 52778 return function setDirection( dir ) { 52779 52780 // dir is assumed to be normalized 52781 52782 if ( dir.y > 0.99999 ) { 52783 52784 this.quaternion.set( 0, 0, 0, 1 ); 52785 52786 } else if ( dir.y < - 0.99999 ) { 52787 52788 this.quaternion.set( 1, 0, 0, 0 ); 52789 52790 } else { 52791 52792 axis.set( dir.z, 0, - dir.x ).normalize(); 52793 52794 radians = Math.acos( dir.y ); 52795 52796 this.quaternion.setFromAxisAngle( axis, radians ); 52797 52798 } 52799 52800 }; 52801 52802 }() ); 52803 52804 ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { 52805 52806 if ( headLength === undefined ) headLength = 0.2 * length; 52807 if ( headWidth === undefined ) headWidth = 0.2 * headLength; 52808 52809 this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 ); 52810 this.line.updateMatrix(); 52811 52812 this.cone.scale.set( headWidth, headLength, headWidth ); 52813 this.cone.position.y = length; 52814 this.cone.updateMatrix(); 52815 52816 }; 52817 52818 ArrowHelper.prototype.setColor = function ( color ) { 52819 52820 this.line.material.color.copy( color ); 52821 this.cone.material.color.copy( color ); 52822 52823 }; 52824 52825 /** 52826 * @author sroucheray / http://sroucheray.org/ 52827 * @author mrdoob / http://mrdoob.com/ 52828 */ 52829 52830 function AxesHelper( size ) { 52831 52832 size = size || 1; 52833 52834 var vertices = [ 52835 0, 0, 0, size, 0, 0, 52836 0, 0, 0, 0, size, 0, 52837 0, 0, 0, 0, 0, size 52838 ]; 52839 52840 var colors = [ 52841 1, 0, 0, 1, 0.6, 0, 52842 0, 1, 0, 0.6, 1, 0, 52843 0, 0, 1, 0, 0.6, 1 52844 ]; 52845 52846 var geometry = new BufferGeometry(); 52847 geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); 52848 geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); 52849 52850 var material = new LineBasicMaterial( { vertexColors: VertexColors } ); 52851 52852 LineSegments.call( this, geometry, material ); 52853 52854 } 52855 52856 AxesHelper.prototype = Object.create( LineSegments.prototype ); 52857 AxesHelper.prototype.constructor = AxesHelper; 52858 52859 // 52860 52861 Curve.create = function ( construct, getPoint ) { 52862 52863 console.log( 'THREE.Curve.create() has been deprecated' ); 52864 52865 construct.prototype = Object.create( Curve.prototype ); 52866 construct.prototype.constructor = construct; 52867 construct.prototype.getPoint = getPoint; 52868 52869 return construct; 52870 52871 }; 52872 52873 // 52874 52875 Object.assign( CurvePath.prototype, { 52876
52877 createPointsGeometry: function ( divisions ) { 52878 52879 console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 52880 52881 // generate geometry from path points (for Line or Points objects) 52882 52883 var pts = this.getPoints( divisions ); 52884 return this.createGeometry( pts ); 52885 52886 }, 52887 52888 createSpacedPointsGeometry: function ( divisions ) { 52889 52890 console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 52891 52892 // generate geometry from equidistant sampling along the path 52893 52894 var pts = this.getSpacedPoints( divisions ); 52895 return this.createGeometry( pts ); 52896 52897 }, 52898 52899 createGeometry: function ( points ) { 52900 52901 console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); 52902 52903 var geometry = new Geometry(); 52904 52905 for ( var i = 0, l = points.length; i < l; i ++ ) { 52906 52907 var point = points[ i ]; 52908 geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); 52909 52910 } 52911 52912 return geometry; 52913 52914 } 52915 52916 } ); 52917 52918 // 52919 52920 Object.assign( Path.prototype, { 52921
52922 fromPoints: function ( points ) { 52923 52924 console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); 52925 this.setFromPoints( points ); 52926 52927 } 52928 52929 } ); 52930 52931 // 52932 52933 function Spline( points ) { 52934 52935 console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' ); 52936 52937 CatmullRomCurve3.call( this, points ); 52938 this.type = 'catmullrom'; 52939 52940 } 52941 52942 Spline.prototype = Object.create( CatmullRomCurve3.prototype ); 52943 52944 Object.assign( Spline.prototype, { 52945 52946 initFromArray: function ( /* a */ ) { 52947 52948 console.error( 'THREE.Spline: .initFromArray() has been removed.' ); 52949 52950 }, 52951 getControlPointsArray: function ( /* optionalTarget */ ) { 52952 52953 console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' ); 52954 52955 }, 52956 reparametrizeByArcLength: function ( /* samplingCoef */ ) { 52957 52958 console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' ); 52959 52960 } 52961 52962 } ); 52963 52964 GridHelper.prototype.setColors = function () { 52965 52966 console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); 52967 52968 }; 52969 52970 SkeletonHelper.prototype.update = function () { 52971 52972 console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' ); 52973 52974 }; 52975 52976 // 52977 52978 Object.assign( Loader.prototype, { 52979
52980 extractUrlBase: function ( url ) { 52981 52982 console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' ); 52983 return LoaderUtils.extractUrlBase( url ); 52984 52985 } 52986 52987 } ); 52988 52989 // 52990 52991 Object.assign( Box2.prototype, { 52992 52993 center: function ( optionalTarget ) { 52994 52995 console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' ); 52996 return this.getCenter( optionalTarget ); 52997 52998 }, 52999 empty: function () { 53000 53001 console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); 53002 return this.isEmpty(); 53003 53004 }, 53005 isIntersectionBox: function ( box ) { 53006 53007 console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); 53008 return this.intersectsBox( box ); 53009 53010 }, 53011 size: function ( optionalTarget ) { 53012 53013 console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' ); 53014 return this.getSize( optionalTarget ); 53015 53016 } 53017 } ); 53018 53019 Object.assign( Box3.prototype, { 53020 53021 center: function ( optionalTarget ) { 53022 53023 console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' ); 53024 return this.getCenter( optionalTarget ); 53025 53026 }, 53027 empty: function () { 53028 53029 console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); 53030 return this.isEmpty(); 53031 53032 }, 53033 isIntersectionBox: function ( box ) { 53034 53035 console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); 53036 return this.intersectsBox( box ); 53037 53038 }, 53039 isIntersectionSphere: function ( sphere ) { 53040 53041 console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); 53042 return this.intersectsSphere( sphere ); 53043 53044 }, 53045 size: function ( optionalTarget ) { 53046 53047 console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' ); 53048 return this.getSize( optionalTarget ); 53049 53050 } 53051 } ); 53052 53053 Line3.prototype.center = function ( optionalTarget ) { 53054 53055 console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); 53056 return this.getCenter( optionalTarget ); 53057 53058 }; 53059 53060 Object.assign( _Math, { 53061 53062 random16: function () { 53063 53064 console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' ); 53065 return Math.random(); 53066 53067 }, 53068 53069 nearestPowerOfTwo: function ( value ) { 53070 53071 console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); 53072 return _Math.floorPowerOfTwo( value ); 53073 53074 }, 53075 53076 nextPowerOfTwo: function ( value ) { 53077 53078 console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); 53079 return _Math.ceilPowerOfTwo( value ); 53080 53081 } 53082 53083 } ); 53084 53085 Object.assign( Matrix3.prototype, { 53086
53087 flattenToArrayOffset: function ( array, offset ) { 53088 53089 console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); 53090 return this.toArray( array, offset ); 53091 53092 }, 53093 multiplyVector3: function ( vector ) { 53094 53095 console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); 53096 return vector.applyMatrix3( this ); 53097 53098 }, 53099 multiplyVector3Array: function ( /* a */ ) { 53100 53101 console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); 53102 53103 }, 53104 applyToBuffer: function ( buffer /*, offset, length */ ) { 53105 53106 console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); 53107 return this.applyToBufferAttribute( buffer ); 53108 53109 }, 53110 applyToVector3Array: function ( /* array, offset, length */ ) { 53111 53112 console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' ); 53113 53114 } 53115 53116 } ); 53117 53118 Object.assign( Matrix4.prototype, { 53119 53120 extractPosition: function ( m ) { 53121 53122 console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); 53123 return this.copyPosition( m ); 53124 53125 }, 53126 flattenToArrayOffset: function ( array, offset ) { 53127 53128 console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); 53129 return this.toArray( array, offset ); 53130 53131 }, 53132 getPosition: function () { 53133 53134 var v1; 53135 53136 return function getPosition() { 53137 53138 if ( v1 === undefined ) v1 = new Vector3(); 53139 console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); 53140 return v1.setFromMatrixColumn( this, 3 ); 53141 53142 }; 53143 53144 }(), 53145 setRotationFromQuaternion: function ( q ) { 53146 53147 console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); 53148 return this.makeRotationFromQuaternion( q ); 53149 53150 }, 53151 multiplyToArray: function () { 53152 53153 console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' ); 53154 53155 }, 53156 multiplyVector3: function ( vector ) { 53157
53158 console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 53159 return vector.applyMatrix4( this ); 53160 53161 }, 53162 multiplyVector4: function ( vector ) { 53163 53164 console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 53165 return vector.applyMatrix4( this ); 53166 53167 }, 53168 multiplyVector3Array: function ( /* a */ ) { 53169 53170 console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' ); 53171 53172 }, 53173 rotateAxis: function ( v ) { 53174 53175 console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); 53176 v.transformDirection( this ); 53177 53178 }, 53179 crossVector: function ( vector ) { 53180 53181 console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); 53182 return vector.applyMatrix4( this ); 53183 53184 }, 53185 translate: function () { 53186 53187 console.error( 'THREE.Matrix4: .translate() has been removed.' ); 53188 53189 }, 53190 rotateX: function () { 53191 53192 console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); 53193 53194 }, 53195 rotateY: function () { 53196 53197 console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); 53198 53199 }, 53200 rotateZ: function () { 53201 53202 console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); 53203 53204 }, 53205 rotateByAxis: function () { 53206 53207 console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); 53208 53209 }, 53210 applyToBuffer: function ( buffer /*, offset, length */ ) { 53211 53212 console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); 53213 return this.applyToBufferAttribute( buffer ); 53214 53215 }, 53216 applyToVector3Array: function ( /* array, offset, length */ ) { 53217 53218 console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' ); 53219 53220 }, 53221 makeFrustum: function ( left, right, bottom, top, near, far ) { 53222 53223 console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' ); 53224 return this.makePerspective( left, right, top, bottom, near, far ); 53225 53226 } 53227 53228 } ); 53229 53230 Plane.prototype.isIntersectionLine = function ( line ) { 53231 53232 console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); 53233 return this.intersectsLine( line ); 53234 53235 }; 53236 53237 Quaternion.prototype.multiplyVector3 = function ( vector ) { 53238
53239 console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); 53240 return vector.applyQuaternion( this ); 53241 53242 }; 53243 53244 Object.assign( Ray.prototype, { 53245 53246 isIntersectionBox: function ( box ) { 53247 53248 console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); 53249 return this.intersectsBox( box ); 53250 53251 }, 53252 isIntersectionPlane: function ( plane ) { 53253 53254 console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); 53255 return this.intersectsPlane( plane ); 53256 53257 }, 53258 isIntersectionSphere: function ( sphere ) { 53259 53260 console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); 53261 return this.intersectsSphere( sphere ); 53262 53263 } 53264 53265 } ); 53266 53267 Object.assign( Triangle.prototype, { 53268 53269 area: function () { 53270 53271 console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' ); 53272 return this.getArea(); 53273 53274 }, 53275 barycoordFromPoint: function ( point, target ) { 53276 53277 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); 53278 return this.getBarycoord( point, target ); 53279 53280 }, 53281 midpoint: function ( target ) { 53282 53283 console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' ); 53284 return this.getMidpoint( target ); 53285 53286 }, 53287 normal: function ( target ) { 53288 53289 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); 53290 return this.getNormal( target ); 53291 53292 }, 53293 plane: function ( target ) { 53294 53295 console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' ); 53296 return this.getPlane( target ); 53297 53298 } 53299 53300 } ); 53301 53302 Object.assign( Triangle, { 53303 53304 barycoordFromPoint: function ( point, a, b, c, target ) { 53305 53306 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); 53307 return Triangle.getBarycoord( point, a, b, c, target ); 53308 53309 }, 53310 normal: function ( a, b, c, target ) { 53311 53312 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); 53313 return Triangle.getNormal( a, b, c, target ); 53314 53315 } 53316 53317 } ); 53318 53319 Object.assign( Shape.prototype, { 53320
53321 extractAllPoints: function ( divisions ) { 53322 53323 console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' ); 53324 return this.extractPoints( divisions ); 53325 53326 }, 53327 extrude: function ( options ) { 53328 53329 console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' ); 53330 return new ExtrudeGeometry( this, options ); 53331 53332 }, 53333 makeGeometry: function ( options ) { 53334 53335 console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' ); 53336 return new ShapeGeometry( this, options ); 53337 53338 } 53339 53340 } ); 53341 53342 Object.assign( Vector2.prototype, { 53343 53344 fromAttribute: function ( attribute, index, offset ) { 53345 53346 console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 53347 return this.fromBufferAttribute( attribute, index, offset ); 53348 53349 }, 53350 distanceToManhattan: function ( v ) { 53351 53352 console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); 53353 return this.manhattanDistanceTo( v ); 53354 53355 }, 53356 lengthManhattan: function () { 53357 53358 console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' ); 53359 return this.manhattanLength(); 53360 53361 } 53362 53363 } ); 53364 53365 Object.assign( Vector3.prototype, { 53366
53367 setEulerFromRotationMatrix: function () { 53368 53369 console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); 53370 53371 }, 53372 setEulerFromQuaternion: function () { 53373 53374 console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); 53375 53376 }, 53377 getPositionFromMatrix: function ( m ) { 53378 53379 console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); 53380 return this.setFromMatrixPosition( m ); 53381 53382 }, 53383 getScaleFromMatrix: function ( m ) { 53384 53385 console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); 53386 return this.setFromMatrixScale( m ); 53387 53388 }, 53389 getColumnFromMatrix: function ( index, matrix ) { 53390 53391 console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); 53392 return this.setFromMatrixColumn( matrix, index ); 53393 53394 }, 53395 applyProjection: function ( m ) { 53396 53397 console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' ); 53398 return this.applyMatrix4( m ); 53399 53400 }, 53401 fromAttribute: function ( attribute, index, offset ) { 53402 53403 console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 53404 return this.fromBufferAttribute( attribute, index, offset ); 53405 53406 }, 53407 distanceToManhattan: function ( v ) { 53408 53409 console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); 53410 return this.manhattanDistanceTo( v ); 53411 53412 }, 53413 lengthManhattan: function () { 53414 53415 console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' ); 53416 return this.manhattanLength(); 53417 53418 } 53419 53420 } ); 53421 53422 Object.assign( Vector4.prototype, { 53423
53424 fromAttribute: function ( attribute, index, offset ) { 53425 53426 console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' ); 53427 return this.fromBufferAttribute( attribute, index, offset ); 53428 53429 }, 53430 lengthManhattan: function () { 53431 53432 console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' ); 53433 return this.manhattanLength(); 53434 53435 } 53436 53437 } ); 53438 53439 // 53440 53441 Object.assign( Geometry.prototype, { 53442 53443 computeTangents: function () { 53444 53445 console.error( 'THREE.Geometry: .computeTangents() has been removed.' ); 53446 53447 }, 53448 computeLineDistances: function () { 53449 53450 console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); 53451 53452 } 53453 53454 } ); 53455 53456 Object.assign( Object3D.prototype, { 53457 53458 getChildByName: function ( name ) { 53459 53460 console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); 53461 return this.getObjectByName( name ); 53462 53463 }, 53464 renderDepth: function () { 53465 53466 console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); 53467 53468 }, 53469 translate: function ( distance, axis ) { 53470 53471 console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); 53472 return this.translateOnAxis( axis, distance ); 53473 53474 }, 53475 getWorldRotation: function () { 53476 53477 console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); 53478 53479 } 53480 53481 } ); 53482 53483 Object.defineProperties( Object3D.prototype, { 53484
vendor: 4,278 bytes, lines 53485-53680
53485 eulerOrder: { 53486 get: function () { 53487 53488 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); 53489 return this.rotation.order; 53490 53491 }, 53492 set: function ( value ) { 53493 53494 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); 53495 this.rotation.order = value; 53496 53497 } 53498 }, 53499 useQuaternion: { 53500 get: function () { 53501 53502 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); 53503 53504 }, 53505 set: function () { 53506 53507 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); 53508 53509 } 53510 } 53511 53512 } ); 53513 53514 Object.defineProperties( LOD.prototype, { 53515 53516 objects: { 53517 get: function () { 53518 53519 console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); 53520 return this.levels; 53521 53522 } 53523 } 53524 53525 } ); 53526 53527 Object.defineProperty( Skeleton.prototype, 'useVertexTexture', { 53528 53529 get: function () { 53530 53531 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); 53532 53533 }, 53534 set: function () { 53535 53536 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); 53537 53538 } 53539 53540 } ); 53541 53542 Object.defineProperty( Curve.prototype, '__arcLengthDivisions', { 53543 53544 get: function () { 53545 53546 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); 53547 return this.arcLengthDivisions; 53548 53549 }, 53550 set: function ( value ) { 53551 53552 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); 53553 this.arcLengthDivisions = value; 53554 53555 } 53556 53557 } ); 53558 53559 // 53560 53561 PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) { 53562 53563 console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + 53564 "Use .setFocalLength and .filmGauge for a photographic setup." ); 53565 53566 if ( filmGauge !== undefined ) this.filmGauge = filmGauge; 53567 this.setFocalLength( focalLength ); 53568 53569 }; 53570 53571 // 53572 53573 Object.defineProperties( Light.prototype, { 53574 onlyShadow: { 53575 set: function () { 53576 53577 console.warn( 'THREE.Light: .onlyShadow has been removed.' ); 53578 53579 } 53580 }, 53581 shadowCameraFov: { 53582 set: function ( value ) { 53583 53584 console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' ); 53585 this.shadow.camera.fov = value; 53586 53587 } 53588 }, 53589 shadowCameraLeft: { 53590 set: function ( value ) { 53591 53592 console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' ); 53593 this.shadow.camera.left = value; 53594 53595 } 53596 }, 53597 shadowCameraRight: { 53598 set: function ( value ) { 53599 53600 console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' ); 53601 this.shadow.camera.right = value; 53602 53603 } 53604 }, 53605 shadowCameraTop: { 53606 set: function ( value ) { 53607 53608 console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' ); 53609 this.shadow.camera.top = value; 53610 53611 } 53612 }, 53613 shadowCameraBottom: { 53614 set: function ( value ) { 53615 53616 console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' ); 53617 this.shadow.camera.bottom = value; 53618 53619 } 53620 }, 53621 shadowCameraNear: { 53622 set: function ( value ) { 53623 53624 console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' ); 53625 this.shadow.camera.near = value; 53626 53627 } 53628 }, 53629 shadowCameraFar: { 53630 set: function ( value ) { 53631 53632 console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' ); 53633 this.shadow.camera.far = value; 53634 53635 } 53636 }, 53637 shadowCameraVisible: { 53638 set: function () { 53639 53640 console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' ); 53641 53642 } 53643 }, 53644 shadowBias: { 53645 set: function ( value ) { 53646 53647 console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' ); 53648 this.shadow.bias = value; 53649 53650 } 53651 }, 53652 shadowDarkness: { 53653 set: function () { 53654 53655 console.warn( 'THREE.Light: .shadowDarkness has been removed.' ); 53656 53657 } 53658 }, 53659 shadowMapWidth: { 53660 set: function ( value ) { 53661 53662 console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' ); 53663 this.shadow.mapSize.width = value; 53664 53665 } 53666 }, 53667 shadowMapHeight: { 53668 set: function ( value ) { 53669 53670 console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' ); 53671 this.shadow.mapSize.height = value; 53672 53673 } 53674 } 53675 } ); 53676 53677 // 53678 53679 Object.defineProperties( BufferAttribute.prototype, { 53680
vendor: 1,325 bytes, lines 53681-53736
53681 length: { 53682 get: function () { 53683 53684 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' ); 53685 return this.array.length; 53686 53687 } 53688 }, 53689 copyIndicesArray: function ( /* indices */ ) { 53690 53691 console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); 53692 53693 } 53694 53695 } ); 53696 53697 Object.assign( BufferGeometry.prototype, { 53698 53699 addIndex: function ( index ) { 53700 53701 console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); 53702 this.setIndex( index ); 53703 53704 }, 53705 addDrawCall: function ( start, count, indexOffset ) { 53706 53707 if ( indexOffset !== undefined ) { 53708 53709 console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); 53710 53711 } 53712 console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); 53713 this.addGroup( start, count ); 53714 53715 }, 53716 clearDrawCalls: function () { 53717 53718 console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); 53719 this.clearGroups(); 53720 53721 }, 53722 computeTangents: function () { 53723 53724 console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); 53725 53726 }, 53727 computeOffsets: function () { 53728 53729 console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); 53730 53731 } 53732 53733 } ); 53734 53735 Object.defineProperties( BufferGeometry.prototype, { 53736
vendor: 1,232 bytes, lines 53737-53805
53737 drawcalls: { 53738 get: function () { 53739 53740 console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' ); 53741 return this.groups; 53742 53743 } 53744 }, 53745 offsets: { 53746 get: function () { 53747 53748 console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' ); 53749 return this.groups; 53750 53751 } 53752 } 53753 53754 } ); 53755 53756 // 53757 53758 Object.assign( ExtrudeBufferGeometry.prototype, { 53759 53760 getArrays: function () { 53761 53762 console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' ); 53763 53764 }, 53765 53766 addShapeList: function () { 53767 53768 console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' ); 53769 53770 }, 53771 53772 addShape: function () { 53773 53774 console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' ); 53775 53776 } 53777 53778 } ); 53779 53780 // 53781 53782 Object.defineProperties( Uniform.prototype, { 53783 53784 dynamic: { 53785 set: function () { 53786 53787 console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' ); 53788 53789 } 53790 }, 53791 onUpdate: { 53792 value: function () { 53793 53794 console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' ); 53795 return this; 53796 53797 } 53798 } 53799 53800 } ); 53801 53802 // 53803 53804 Object.defineProperties( Material.prototype, { 53805
vendor: 1,204 bytes, lines 53806-53862
53806 wrapAround: { 53807 get: function () { 53808 53809 console.warn( 'THREE.Material: .wrapAround has been removed.' ); 53810 53811 }, 53812 set: function () { 53813 53814 console.warn( 'THREE.Material: .wrapAround has been removed.' ); 53815 53816 } 53817 }, 53818 wrapRGB: { 53819 get: function () { 53820 53821 console.warn( 'THREE.Material: .wrapRGB has been removed.' ); 53822 return new Color(); 53823 53824 } 53825 }, 53826 53827 shading: { 53828 get: function () { 53829 53830 console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 53831 53832 }, 53833 set: function ( value ) { 53834 53835 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); 53836 this.flatShading = ( value === FlatShading ); 53837 53838 } 53839 } 53840 53841 } ); 53842 53843 Object.defineProperties( MeshPhongMaterial.prototype, { 53844 53845 metal: { 53846 get: function () { 53847 53848 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' ); 53849 return false; 53850 53851 }, 53852 set: function () { 53853 53854 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' ); 53855 53856 } 53857 } 53858 53859 } ); 53860 53861 Object.defineProperties( ShaderMaterial.prototype, { 53862
vendor: 4,060 bytes, lines 53863-54002
53863 derivatives: { 53864 get: function () { 53865 53866 console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); 53867 return this.extensions.derivatives; 53868 53869 }, 53870 set: function ( value ) { 53871 53872 console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); 53873 this.extensions.derivatives = value; 53874 53875 } 53876 } 53877 53878 } ); 53879 53880 // 53881 53882 Object.assign( WebGLRenderer.prototype, { 53883 53884 animate: function ( callback ) { 53885 53886 console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' ); 53887 this.setAnimationLoop( callback ); 53888 53889 }, 53890 53891 getCurrentRenderTarget: function () { 53892 53893 console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' ); 53894 return this.getRenderTarget(); 53895 53896 }, 53897 53898 getMaxAnisotropy: function () { 53899 53900 console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' ); 53901 return this.capabilities.getMaxAnisotropy(); 53902 53903 }, 53904 53905 getPrecision: function () { 53906 53907 console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' ); 53908 return this.capabilities.precision; 53909 53910 }, 53911 53912 resetGLState: function () { 53913 53914 console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' ); 53915 return this.state.reset(); 53916 53917 }, 53918 53919 supportsFloatTextures: function () { 53920 53921 console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); 53922 return this.extensions.get( 'OES_texture_float' ); 53923 53924 }, 53925 supportsHalfFloatTextures: function () { 53926 53927 console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); 53928 return this.extensions.get( 'OES_texture_half_float' ); 53929 53930 }, 53931 supportsStandardDerivatives: function () { 53932 53933 console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); 53934 return this.extensions.get( 'OES_standard_derivatives' ); 53935 53936 }, 53937 supportsCompressedTextureS3TC: function () { 53938 53939 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); 53940 return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); 53941 53942 }, 53943 supportsCompressedTexturePVRTC: function () { 53944 53945 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); 53946 return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); 53947 53948 }, 53949 supportsBlendMinMax: function () { 53950 53951 console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); 53952 return this.extensions.get( 'EXT_blend_minmax' ); 53953 53954 }, 53955 supportsVertexTextures: function () { 53956 53957 console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' ); 53958 return this.capabilities.vertexTextures; 53959 53960 }, 53961 supportsInstancedArrays: function () { 53962 53963 console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); 53964 return this.extensions.get( 'ANGLE_instanced_arrays' ); 53965 53966 }, 53967 enableScissorTest: function ( boolean ) { 53968 53969 console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); 53970 this.setScissorTest( boolean ); 53971 53972 }, 53973 initMaterial: function () { 53974 53975 console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); 53976 53977 }, 53978 addPrePlugin: function () { 53979 53980 console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); 53981 53982 }, 53983 addPostPlugin: function () { 53984 53985 console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); 53986 53987 }, 53988 updateShadowMap: function () { 53989 53990 console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); 53991 53992 }, 53993 setFaceCulling: function () { 53994 53995 console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' ); 53996 53997 } 53998 53999 } ); 54000 54001 Object.defineProperties( WebGLRenderer.prototype, { 54002
54003 shadowMapEnabled: { 54004 get: function () { 54005 54006 return this.shadowMap.enabled; 54007 54008 }, 54009 set: function ( value ) { 54010 54011 console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' ); 54012 this.shadowMap.enabled = value; 54013 54014 } 54015 }, 54016 shadowMapType: { 54017 get: function () { 54018 54019 return this.shadowMap.type; 54020 54021 }, 54022 set: function ( value ) { 54023 54024 console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' ); 54025 this.shadowMap.type = value; 54026 54027 } 54028 }, 54029 shadowMapCullFace: { 54030 get: function () { 54031 54032 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); 54033 return undefined; 54034 54035 }, 54036 set: function ( /* value */ ) { 54037 54038 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); 54039 54040 } 54041 } 54042 } ); 54043 54044 Object.defineProperties( WebGLShadowMap.prototype, { 54045 54046 cullFace: { 54047 get: function () { 54048 54049 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); 54050 return undefined; 54051 54052 }, 54053 set: function ( /* cullFace */ ) { 54054 54055 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); 54056 54057 } 54058 }, 54059 renderReverseSided: { 54060 get: function () { 54061 54062 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); 54063 return undefined; 54064 54065 }, 54066 set: function () { 54067 54068 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); 54069 54070 } 54071 }, 54072 renderSingleSided: { 54073 get: function () { 54074 54075 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); 54076 return undefined; 54077 54078 }, 54079 set: function () { 54080 54081 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); 54082 54083 } 54084 } 54085 54086 } ); 54087 54088 // 54089 54090 Object.defineProperties( WebGLRenderTarget.prototype, { 54091
54092 wrapS: { 54093 get: function () { 54094 54095 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); 54096 return this.texture.wrapS; 54097 54098 }, 54099 set: function ( value ) { 54100 54101 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); 54102 this.texture.wrapS = value; 54103 54104 } 54105 }, 54106 wrapT: { 54107 get: function () { 54108 54109 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); 54110 return this.texture.wrapT; 54111 54112 }, 54113 set: function ( value ) { 54114 54115 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); 54116 this.texture.wrapT = value; 54117 54118 } 54119 }, 54120 magFilter: { 54121 get: function () { 54122 54123 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); 54124 return this.texture.magFilter; 54125 54126 }, 54127 set: function ( value ) { 54128 54129 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); 54130 this.texture.magFilter = value; 54131 54132 } 54133 }, 54134 minFilter: { 54135 get: function () { 54136 54137 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); 54138 return this.texture.minFilter; 54139 54140 }, 54141 set: function ( value ) { 54142 54143 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); 54144 this.texture.minFilter = value; 54145 54146 } 54147 }, 54148 anisotropy: { 54149 get: function () { 54150 54151 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); 54152 return this.texture.anisotropy; 54153 54154 }, 54155 set: function ( value ) { 54156 54157 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); 54158 this.texture.anisotropy = value; 54159 54160 } 54161 }, 54162 offset: { 54163 get: function () { 54164 54165 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); 54166 return this.texture.offset; 54167 54168 }, 54169 set: function ( value ) { 54170 54171 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); 54172 this.texture.offset = value; 54173 54174 } 54175 }, 54176 repeat: { 54177 get: function () { 54178 54179 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); 54180 return this.texture.repeat; 54181 54182 }, 54183 set: function ( value ) { 54184 54185 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); 54186 this.texture.repeat = value; 54187 54188 } 54189 }, 54190 format: { 54191 get: function () { 54192 54193 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); 54194 return this.texture.format; 54195 54196 }, 54197 set: function ( value ) { 54198 54199 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); 54200 this.texture.format = value; 54201 54202 } 54203 }, 54204 type: { 54205 get: function () { 54206 54207 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); 54208 return this.texture.type; 54209 54210 }, 54211 set: function ( value ) { 54212 54213 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); 54214 this.texture.type = value; 54215 54216 } 54217 }, 54218 generateMipmaps: { 54219 get: function () { 54220 54221 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); 54222 return this.texture.generateMipmaps; 54223 54224 }, 54225 set: function ( value ) { 54226 54227 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); 54228 this.texture.generateMipmaps = value; 54229 54230 } 54231 } 54232 54233 } ); 54234 54235 // 54236 54237 Object.defineProperties( WebVRManager.prototype, { 54238
vendor: 4,336 bytes, lines 54239-54466
54239 standing: { 54240 set: function ( /* value */ ) { 54241 54242 console.warn( 'THREE.WebVRManager: .standing has been removed.' ); 54243 54244 } 54245 } 54246 54247 } ); 54248 54249 // 54250 54251 Audio.prototype.load = function ( file ) { 54252 54253 console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); 54254 var scope = this; 54255 var audioLoader = new AudioLoader(); 54256 audioLoader.load( file, function ( buffer ) { 54257 54258 scope.setBuffer( buffer ); 54259 54260 } ); 54261 return this; 54262 54263 }; 54264 54265 AudioAnalyser.prototype.getData = function () { 54266 54267 console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); 54268 return this.getFrequencyData(); 54269 54270 }; 54271 54272 // 54273 54274 CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) { 54275 54276 console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' ); 54277 return this.update( renderer, scene ); 54278 54279 }; 54280 54281 /** 54282 * @author dmarcos / https://github.com/dmarcos 54283 * @author mrdoob / http://mrdoob.com 54284 */ 54285 var VRControls = function ( object, onError ) { 54286 54287 var scope = this; 54288 54289 var vrDisplay, vrDisplays; 54290 54291 var standingMatrix = new Matrix4(); 54292 54293 var frameData = null; 54294 54295 if ( 'VRFrameData' in window ) { 54296 54297 frameData = new VRFrameData(); 54298 54299 } 54300 54301 function gotVRDisplays( displays ) { 54302 54303 vrDisplays = displays; 54304 54305 if ( displays.length > 0 ) { 54306 54307 vrDisplay = displays[ 0 ]; 54308 54309 } else { 54310 54311 if ( onError ) onError( 'VR input not available.' ); 54312 54313 } 54314 54315 } 54316 54317 if ( navigator.getVRDisplays ) { 54318 54319 navigator.getVRDisplays().then( gotVRDisplays ).catch( function () { 54320 54321 console.warn( 'VRControls: Unable to get VR Displays' ); 54322 54323 } ); 54324 54325 } 54326 54327 // the Rift SDK returns the position in meters 54328 // this scale factor allows the user to define how meters 54329 // are converted to scene units. 54330 54331 this.scale = 1; 54332 54333 // If true will use "standing space" coordinate system where y=0 is the 54334 // floor and x=0, z=0 is the center of the room. 54335 this.standing = false; 54336 54337 // Distance from the users eyes to the floor in meters. Used when 54338 // standing=true but the VRDisplay doesn't provide stageParameters. 54339 this.userHeight = 1.6; 54340 54341 this.getVRDisplay = function () { 54342 54343 return vrDisplay; 54344 54345 }; 54346 54347 this.setVRDisplay = function ( value ) { 54348 54349 vrDisplay = value; 54350 54351 }; 54352 54353 this.getVRDisplays = function () { 54354 54355 console.warn( 'VRControls: getVRDisplays() is being deprecated.' ); 54356 return vrDisplays; 54357 54358 }; 54359 54360 this.getStandingMatrix = function () { 54361 54362 return standingMatrix; 54363 54364 }; 54365 54366 this.update = function () { 54367 54368 if ( vrDisplay ) { 54369 54370 var pose; 54371 54372 if ( vrDisplay.getFrameData ) { 54373 54374 vrDisplay.getFrameData( frameData ); 54375 pose = frameData.pose; 54376 54377 } else if ( vrDisplay.getPose ) { 54378 54379 pose = vrDisplay.getPose(); 54380 54381 } 54382 54383 if ( pose.orientation !== null ) { 54384 54385 object.quaternion.fromArray( pose.orientation ); 54386 54387 } 54388 54389 if ( pose.position !== null ) { 54390 54391 object.position.fromArray( pose.position ); 54392 54393 } else { 54394 54395 object.position.set( 0, 0, 0 ); 54396 54397 } 54398 54399 if ( this.standing ) { 54400 54401 if ( vrDisplay.stageParameters ) { 54402 54403 object.updateMatrix(); 54404 54405 standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform ); 54406 object.applyMatrix( standingMatrix ); 54407 54408 } else { 54409 54410 object.position.setY( object.position.y + this.userHeight ); 54411 54412 } 54413 54414 } 54415 54416 object.position.multiplyScalar( scope.scale ); 54417 54418 } 54419 54420 }; 54421 54422 this.dispose = function () { 54423 54424 vrDisplay = null; 54425 54426 }; 54427 54428 }; 54429 54430 /** 54431 * @author dmarcos / https://github.com/dmarcos 54432 * @author mrdoob / http://mrdoob.com 54433 * 54434 * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html 54435 * 54436 * Firefox: http://mozvr.com/downloads/ 54437 * Chromium: https://webvr.info/get-chrome 54438 */ 54439 var VREffect = function ( renderer, onError ) { 54440 54441 var vrDisplay, vrDisplays; 54442 var eyeTranslationL = new Vector3(); 54443 var eyeTranslationR = new Vector3(); 54444 var renderRectL, renderRectR; 54445 var headMatrix = new Matrix4(); 54446 var eyeMatrixL = new Matrix4(); 54447 var eyeMatrixR = new Matrix4(); 54448 54449 var frameData = null; 54450 54451 if ( 'VRFrameData' in window ) { 54452 54453 frameData = new window.VRFrameData(); 54454 54455 } 54456 54457 function gotVRDisplays( displays ) { 54458 54459 vrDisplays = displays; 54460 54461 if ( displays.length > 0 ) { 54462 54463 vrDisplay = displays[ 0 ]; 54464 54465 } else { 54466
vendor: 22,864 bytes, lines 54467-55330
54467 if ( onError ) onError( 'HMD not available' ); 54468 54469 } 54470 54471 } 54472 54473 if ( navigator.getVRDisplays ) { 54474 54475 navigator.getVRDisplays().then( gotVRDisplays ).catch( function () { 54476 54477 console.warn( 'VREffect: Unable to get VR Displays' ); 54478 54479 } ); 54480 54481 } 54482 54483 // 54484 54485 this.isPresenting = false; 54486 54487 var scope = this; 54488 54489 var rendererSize = renderer.getSize(); 54490 var rendererUpdateStyle = false; 54491 var rendererPixelRatio = renderer.getPixelRatio(); 54492 54493 this.getVRDisplay = function () { 54494 54495 return vrDisplay; 54496 54497 }; 54498 54499 this.setVRDisplay = function ( value ) { 54500 54501 vrDisplay = value; 54502 54503 }; 54504 54505 this.getVRDisplays = function () { 54506 54507 console.warn( 'VREffect: getVRDisplays() is being deprecated.' ); 54508 return vrDisplays; 54509 54510 }; 54511 54512 this.setSize = function ( width, height, updateStyle ) { 54513 54514 rendererSize = { width: width, height: height }; 54515 rendererUpdateStyle = updateStyle; 54516 54517 if ( scope.isPresenting ) { 54518 54519 var eyeParamsL = vrDisplay.getEyeParameters( 'left' ); 54520 renderer.setPixelRatio( 1 ); 54521 renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false ); 54522 54523 } else { 54524 54525 renderer.setPixelRatio( rendererPixelRatio ); 54526 renderer.setSize( width, height, updateStyle ); 54527 54528 } 54529 54530 }; 54531 54532 // VR presentation 54533 54534 var canvas = renderer.domElement; 54535 var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ]; 54536 var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ]; 54537 54538 function onVRDisplayPresentChange() { 54539 54540 var wasPresenting = scope.isPresenting; 54541 scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting; 54542 54543 if ( scope.isPresenting ) { 54544 54545 var eyeParamsL = vrDisplay.getEyeParameters( 'left' ); 54546 var eyeWidth = eyeParamsL.renderWidth; 54547 var eyeHeight = eyeParamsL.renderHeight; 54548 54549 if ( ! wasPresenting ) { 54550 54551 rendererPixelRatio = renderer.getPixelRatio(); 54552 rendererSize = renderer.getSize(); 54553 54554 renderer.setPixelRatio( 1 ); 54555 renderer.setSize( eyeWidth * 2, eyeHeight, false ); 54556 54557 } 54558 54559 } else if ( wasPresenting ) { 54560 54561 renderer.setPixelRatio( rendererPixelRatio ); 54562 renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle ); 54563 54564 } 54565 54566 } 54567 54568 window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); 54569 54570 this.setFullScreen = function ( boolean ) { 54571 54572 return new Promise( function ( resolve, reject ) { 54573 54574 if ( vrDisplay === undefined ) { 54575 54576 reject( new Error( 'No VR hardware found.' ) ); 54577 return; 54578 54579 } 54580 54581 if ( scope.isPresenting === boolean ) { 54582 54583 resolve(); 54584 return; 54585 54586 } 54587 54588 if ( boolean ) { 54589 54590 resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) ); 54591 54592 } else { 54593 54594 resolve( vrDisplay.exitPresent() ); 54595 54596 } 54597 54598 } ); 54599 54600 }; 54601 54602 this.requestPresent = function () { 54603 54604 return this.setFullScreen( true ); 54605 54606 }; 54607 54608 this.exitPresent = function () { 54609 54610 return this.setFullScreen( false ); 54611 54612 }; 54613 54614 this.requestAnimationFrame = function ( f ) { 54615 54616 if ( vrDisplay !== undefined ) { 54617 54618 return vrDisplay.requestAnimationFrame( f ); 54619 54620 } else { 54621 54622 return window.requestAnimationFrame( f ); 54623 54624 } 54625 54626 }; 54627 54628 this.cancelAnimationFrame = function ( h ) { 54629 54630 if ( vrDisplay !== undefined ) { 54631 54632 vrDisplay.cancelAnimationFrame( h ); 54633 54634 } else { 54635 54636 window.cancelAnimationFrame( h ); 54637 54638 } 54639 54640 }; 54641 54642 this.submitFrame = function () { 54643 54644 if ( vrDisplay !== undefined && scope.isPresenting ) { 54645 54646 vrDisplay.submitFrame(); 54647 54648 } 54649 54650 }; 54651 54652 this.autoSubmitFrame = true; 54653 54654 // render 54655 54656 var cameraL = new PerspectiveCamera(); 54657 cameraL.layers.enable( 1 ); 54658 54659 var cameraR = new PerspectiveCamera(); 54660 cameraR.layers.enable( 2 ); 54661 54662 this.render = function ( scene, camera, renderTarget, forceClear ) { 54663 54664 if ( vrDisplay && scope.isPresenting ) { 54665 54666 var autoUpdate = scene.autoUpdate; 54667 54668 if ( autoUpdate ) { 54669 54670 scene.updateMatrixWorld(); 54671 scene.autoUpdate = false; 54672 54673 } 54674 54675 if ( Array.isArray( scene ) ) { 54676 54677 console.warn( 'VREffect.render() no longer supports arrays. Use object.layers instead.' ); 54678 scene = scene[ 0 ]; 54679 54680 } 54681 54682 // When rendering we don't care what the recommended size is, only what the actual size 54683 // of the backbuffer is. 54684 var size = renderer.getSize(); 54685 var layers = vrDisplay.getLayers(); 54686 var leftBounds; 54687 var rightBounds; 54688 54689 if ( layers.length ) { 54690 54691 var layer = layers[ 0 ]; 54692 54693 leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds; 54694 rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds; 54695 54696 } else { 54697 54698 leftBounds = defaultLeftBounds; 54699 rightBounds = defaultRightBounds; 54700 54701 } 54702 54703 renderRectL = { 54704 x: Math.round( size.width * leftBounds[ 0 ] ), 54705 y: Math.round( size.height * leftBounds[ 1 ] ), 54706 width: Math.round( size.width * leftBounds[ 2 ] ), 54707 height: Math.round( size.height * leftBounds[ 3 ] ) 54708 }; 54709 renderRectR = { 54710 x: Math.round( size.width * rightBounds[ 0 ] ), 54711 y: Math.round( size.height * rightBounds[ 1 ] ), 54712 width: Math.round( size.width * rightBounds[ 2 ] ), 54713 height: Math.round( size.height * rightBounds[ 3 ] ) 54714 }; 54715 54716 if ( renderTarget ) { 54717 54718 renderer.setRenderTarget( renderTarget ); 54719 renderTarget.scissorTest = true; 54720 54721 } else { 54722 54723 renderer.setRenderTarget( null ); 54724 renderer.setScissorTest( true ); 54725 54726 } 54727 54728 if ( renderer.autoClear || forceClear ) renderer.clear(); 54729 54730 if ( camera.parent === null ) camera.updateMatrixWorld(); 54731 54732 camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale ); 54733 54734 cameraR.position.copy( cameraL.position ); 54735 cameraR.quaternion.copy( cameraL.quaternion ); 54736 cameraR.scale.copy( cameraL.scale ); 54737 54738 if ( vrDisplay.getFrameData ) { 54739 54740 vrDisplay.depthNear = camera.near; 54741 vrDisplay.depthFar = camera.far; 54742 54743 vrDisplay.getFrameData( frameData ); 54744 54745 cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix; 54746 cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix; 54747 54748 getEyeMatrices( frameData ); 54749 54750 cameraL.updateMatrix(); 54751 cameraL.matrix.multiply( eyeMatrixL ); 54752 cameraL.matrix.decompose( cameraL.position, cameraL.quaternion, cameraL.scale ); 54753 54754 cameraR.updateMatrix(); 54755 cameraR.matrix.multiply( eyeMatrixR ); 54756 cameraR.matrix.decompose( cameraR.position, cameraR.quaternion, cameraR.scale ); 54757 54758 } else { 54759 54760 var eyeParamsL = vrDisplay.getEyeParameters( 'left' ); 54761 var eyeParamsR = vrDisplay.getEyeParameters( 'right' ); 54762 54763 cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far ); 54764 cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far ); 54765 54766 eyeTranslationL.fromArray( eyeParamsL.offset ); 54767 eyeTranslationR.fromArray( eyeParamsR.offset ); 54768 54769 cameraL.translateOnAxis( eyeTranslationL, cameraL.scale.x ); 54770 cameraR.translateOnAxis( eyeTranslationR, cameraR.scale.x ); 54771 54772 } 54773 54774 // render left eye 54775 if ( renderTarget ) { 54776 54777 renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 54778 renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 54779 54780 } else { 54781 54782 renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 54783 renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 54784 54785 } 54786 renderer.render( scene, cameraL, renderTarget, forceClear ); 54787 54788 // render right eye 54789 if ( renderTarget ) { 54790 54791 renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 54792 renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 54793 54794 } else { 54795 54796 renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 54797 renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 54798 54799 } 54800 renderer.render( scene, cameraR, renderTarget, forceClear ); 54801 54802 if ( renderTarget ) { 54803 54804 renderTarget.viewport.set( 0, 0, size.width, size.height ); 54805 renderTarget.scissor.set( 0, 0, size.width, size.height ); 54806 renderTarget.scissorTest = false; 54807 renderer.setRenderTarget( null ); 54808 54809 } else { 54810 54811 renderer.setViewport( 0, 0, size.width, size.height ); 54812 renderer.setScissorTest( false ); 54813 54814 } 54815 54816 if ( autoUpdate ) { 54817 54818 scene.autoUpdate = true; 54819 54820 } 54821 54822 if ( scope.autoSubmitFrame ) { 54823 54824 scope.submitFrame(); 54825 54826 } 54827 54828 return; 54829 54830 } 54831 54832 // Regular render mode if not HMD 54833 54834 renderer.render( scene, camera, renderTarget, forceClear ); 54835 54836 }; 54837 54838 this.dispose = function () { 54839 54840 window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); 54841 54842 }; 54843 54844 // 54845 54846 var poseOrientation = new Quaternion(); 54847 var posePosition = new Vector3(); 54848 54849 // Compute model matrices of the eyes with respect to the head. 54850 function getEyeMatrices( frameData ) { 54851 54852 // Compute the matrix for the position of the head based on the pose 54853 if ( frameData.pose.orientation ) { 54854 54855 poseOrientation.fromArray( frameData.pose.orientation ); 54856 headMatrix.makeRotationFromQuaternion( poseOrientation ); 54857 54858 } else { 54859 54860 headMatrix.identity(); 54861 54862 } 54863 54864 if ( frameData.pose.position ) { 54865 54866 posePosition.fromArray( frameData.pose.position ); 54867 headMatrix.setPosition( posePosition ); 54868 54869 } 54870 54871 // The view matrix transforms vertices from sitting space to eye space. As such, the view matrix can be thought of as a product of two matrices: 54872 // headToEyeMatrix * sittingToHeadMatrix 54873 54874 // The headMatrix that we've calculated above is the model matrix of the head in sitting space, which is the inverse of sittingToHeadMatrix. 54875 // So when we multiply the view matrix with headMatrix, we're left with headToEyeMatrix: 54876 // viewMatrix * headMatrix = headToEyeMatrix * sittingToHeadMatrix * headMatrix = headToEyeMatrix 54877 54878 eyeMatrixL.fromArray( frameData.leftViewMatrix ); 54879 eyeMatrixL.multiply( headMatrix ); 54880 eyeMatrixR.fromArray( frameData.rightViewMatrix ); 54881 eyeMatrixR.multiply( headMatrix ); 54882 54883 // The eye's model matrix in head space is the inverse of headToEyeMatrix we calculated above. 54884 54885 eyeMatrixL.getInverse( eyeMatrixL ); 54886 eyeMatrixR.getInverse( eyeMatrixR ); 54887 54888 } 54889 54890 function fovToNDCScaleOffset( fov ) { 54891 54892 var pxscale = 2.0 / ( fov.leftTan + fov.rightTan ); 54893 var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5; 54894 var pyscale = 2.0 / ( fov.upTan + fov.downTan ); 54895 var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5; 54896 return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] }; 54897 54898 } 54899 54900 function fovPortToProjection( fov, rightHanded, zNear, zFar ) { 54901 54902 rightHanded = rightHanded === undefined ? true : rightHanded; 54903 zNear = zNear === undefined ? 0.01 : zNear; 54904 zFar = zFar === undefined ? 10000.0 : zFar; 54905 54906 var handednessScale = rightHanded ? - 1.0 : 1.0; 54907 54908 // start with an identity matrix 54909 var mobj = new Matrix4(); 54910 var m = mobj.elements; 54911 54912 // and with scale/offset info for normalized device coords 54913 var scaleAndOffset = fovToNDCScaleOffset( fov ); 54914 54915 // X result, map clip edges to [-w,+w] 54916 m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ]; 54917 m[ 0 * 4 + 1 ] = 0.0; 54918 m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale; 54919 m[ 0 * 4 + 3 ] = 0.0; 54920 54921 // Y result, map clip edges to [-w,+w] 54922 // Y offset is negated because this proj matrix transforms from world coords with Y=up, 54923 // but the NDC scaling has Y=down (thanks D3D?) 54924 m[ 1 * 4 + 0 ] = 0.0; 54925 m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ]; 54926 m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale; 54927 m[ 1 * 4 + 3 ] = 0.0; 54928 54929 // Z result (up to the app) 54930 m[ 2 * 4 + 0 ] = 0.0; 54931 m[ 2 * 4 + 1 ] = 0.0; 54932 m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale; 54933 m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar ); 54934 54935 // W result (= Z in) 54936 m[ 3 * 4 + 0 ] = 0.0; 54937 m[ 3 * 4 + 1 ] = 0.0; 54938 m[ 3 * 4 + 2 ] = handednessScale; 54939 m[ 3 * 4 + 3 ] = 0.0; 54940 54941 mobj.transpose(); 54942 return mobj; 54943 54944 } 54945 54946 function fovToProjection( fov, rightHanded, zNear, zFar ) { 54947 54948 var DEG2RAD = Math.PI / 180.0; 54949 54950 var fovPort = { 54951 upTan: Math.tan( fov.upDegrees * DEG2RAD ), 54952 downTan: Math.tan( fov.downDegrees * DEG2RAD ), 54953 leftTan: Math.tan( fov.leftDegrees * DEG2RAD ), 54954 rightTan: Math.tan( fov.rightDegrees * DEG2RAD ) 54955 }; 54956 54957 return fovPortToProjection( fovPort, rightHanded, zNear, zFar ); 54958 54959 } 54960 54961 }; 54962 54963 /** 54964 * @author qiao / https://github.com/qiao 54965 * @author mrdoob / http://mrdoob.com 54966 * @author alteredq / http://alteredqualia.com/ 54967 * @author WestLangley / http://github.com/WestLangley 54968 * @author erich666 / http://erichaines.com 54969 */ 54970 var OrbitControls = function ( object, domElement ) { 54971 54972 this.object = object; 54973 54974 this.domElement = ( domElement !== undefined ) ? domElement : document; 54975 54976 // Set to false to disable this control 54977 this.enabled = true; 54978 54979 // "target" sets the location of focus, where the object orbits around 54980 this.target = new Vector3(); 54981 54982 // How far you can dolly in and out ( PerspectiveCamera only ) 54983 this.minDistance = 0; 54984 this.maxDistance = Infinity; 54985 54986 // How far you can zoom in and out ( OrthographicCamera only ) 54987 this.minZoom = 0; 54988 this.maxZoom = Infinity; 54989 54990 // How far you can orbit vertically, upper and lower limits. 54991 // Range is 0 to Math.PI radians. 54992 this.minPolarAngle = 0; // radians 54993 this.maxPolarAngle = Math.PI; // radians 54994 54995 // How far you can orbit horizontally, upper and lower limits. 54996 // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. 54997 this.minAzimuthAngle = - Infinity; // radians 54998 this.maxAzimuthAngle = Infinity; // radians 54999 55000 // Set to true to enable damping (inertia) 55001 // If damping is enabled, you must call controls.update() in your animation loop 55002 this.enableDamping = false; 55003 this.dampingFactor = 0.25; 55004 55005 // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. 55006 // Set to false to disable zooming 55007 this.enableZoom = true; 55008 this.zoomSpeed = 1.0; 55009 55010 // Set to false to disable rotating 55011 this.enableRotate = true; 55012 this.rotateSpeed = 1.0; 55013 55014 // Set to false to disable panning 55015 this.enablePan = true; 55016 this.panSpeed = 1.0; 55017 this.screenSpacePanning = false; // if true, pan in screen-space 55018 this.keyPanSpeed = 7.0; // pixels moved per arrow key push 55019 55020 // Set to true to automatically rotate around the target 55021 // If auto-rotate is enabled, you must call controls.update() in your animation loop 55022 this.autoRotate = false; 55023 this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 55024 55025 // Set to false to disable use of the keys 55026 this.enableKeys = true; 55027 55028 // The four arrow keys 55029 this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; 55030 55031 // Mouse buttons 55032 this.mouseButtons = { ORBIT: MOUSE.LEFT, ZOOM: MOUSE.MIDDLE, PAN: MOUSE.RIGHT }; 55033 55034 // for reset 55035 this.target0 = this.target.clone(); 55036 this.position0 = this.object.position.clone(); 55037 this.zoom0 = this.object.zoom; 55038 55039 // 55040 // public methods 55041 // 55042 55043 this.getPolarAngle = function () { 55044 55045 return spherical.phi; 55046 55047 }; 55048 55049 this.getAzimuthalAngle = function () { 55050 55051 return spherical.theta; 55052 55053 }; 55054 55055 this.saveState = function () { 55056 55057 scope.target0.copy( scope.target ); 55058 scope.position0.copy( scope.object.position ); 55059 scope.zoom0 = scope.object.zoom; 55060 55061 }; 55062 55063 this.reset = function () { 55064 55065 scope.target.copy( scope.target0 ); 55066 scope.object.position.copy( scope.position0 ); 55067 scope.object.zoom = scope.zoom0; 55068 55069 scope.object.updateProjectionMatrix(); 55070 scope.dispatchEvent( changeEvent ); 55071 55072 scope.update(); 55073 55074 state = STATE.NONE; 55075 55076 }; 55077 55078 // this method is exposed, but perhaps it would be better if we can make it private... 55079 this.update = function () { 55080 55081 var offset = new Vector3(); 55082 55083 // so camera.up is the orbit axis 55084 var quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) ); 55085 var quatInverse = quat.clone().inverse(); 55086 55087 var lastPosition = new Vector3(); 55088 var lastQuaternion = new Quaternion(); 55089 55090 return function update() { 55091 55092 var position = scope.object.position; 55093 55094 offset.copy( position ).sub( scope.target ); 55095 55096 // rotate offset to "y-axis-is-up" space 55097 offset.applyQuaternion( quat ); 55098 55099 // angle from z-axis around y-axis 55100 spherical.setFromVector3( offset ); 55101 55102 if ( scope.autoRotate && state === STATE.NONE ) { 55103 55104 scope.rotateLeft( getAutoRotationAngle() ); 55105 55106 } 55107 55108 spherical.theta += sphericalDelta.theta; 55109 spherical.phi += sphericalDelta.phi; 55110 55111 // restrict theta to be between desired limits 55112 spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); 55113 55114 // restrict phi to be between desired limits 55115 spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); 55116 55117 spherical.makeSafe(); 55118 55119 55120 spherical.radius *= scale; 55121 55122 // restrict radius to be between desired limits 55123 spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); 55124 55125 // move target to panned location 55126 scope.target.add( panOffset ); 55127 55128 offset.setFromSpherical( spherical ); 55129 55130 // rotate offset back to "camera-up-vector-is-up" space 55131 offset.applyQuaternion( quatInverse ); 55132 55133 position.copy( scope.target ).add( offset ); 55134 55135 scope.object.lookAt( scope.target ); 55136 55137 if ( scope.enableDamping === true ) { 55138 55139 sphericalDelta.theta *= ( 1 - scope.dampingFactor ); 55140 sphericalDelta.phi *= ( 1 - scope.dampingFactor ); 55141 55142 panOffset.multiplyScalar( 1 - scope.dampingFactor ); 55143 55144 } else { 55145 55146 sphericalDelta.set( 0, 0, 0 ); 55147 55148 panOffset.set( 0, 0, 0 ); 55149 55150 } 55151 55152 scale = 1; 55153 55154 // update condition is: 55155 // min(camera displacement, camera rotation in radians)^2 > EPS 55156 // using small-angle approximation cos(x/2) = 1 - x^2 / 8 55157 55158 if ( zoomChanged || 55159 lastPosition.distanceToSquared( scope.object.position ) > EPS || 55160 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { 55161 55162 scope.dispatchEvent( changeEvent ); 55163 55164 lastPosition.copy( scope.object.position ); 55165 lastQuaternion.copy( scope.object.quaternion ); 55166 zoomChanged = false; 55167 55168 return true; 55169 55170 } 55171 55172 return false; 55173 55174 }; 55175 55176 }(); 55177 55178 this.dispose = function () { 55179 55180 scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); 55181 scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); 55182 scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); 55183 55184 scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); 55185 scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); 55186 scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); 55187 55188 document.removeEventListener( 'mousemove', onMouseMove, false ); 55189 document.removeEventListener( 'mouseup', onMouseUp, false ); 55190 55191 window.removeEventListener( 'keydown', onKeyDown, false ); 55192 55193 //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? 55194 55195 }; 55196 55197 // 55198 // internals 55199 // 55200 55201 var scope = this; 55202 55203 var changeEvent = { type: 'change' }; 55204 var startEvent = { type: 'start' }; 55205 var endEvent = { type: 'end' }; 55206 55207 var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 }; 55208 55209 var state = STATE.NONE; 55210 55211 var EPS = 0.000001; 55212 55213 // current position in spherical coordinates 55214 var spherical = new Spherical(); 55215 var sphericalDelta = new Spherical(); 55216 55217 var scale = 1; 55218 var panOffset = new Vector3(); 55219 var zoomChanged = false; 55220 55221 var rotateStart = new Vector2(); 55222 var rotateEnd = new Vector2(); 55223 var rotateDelta = new Vector2(); 55224 55225 var panStart = new Vector2(); 55226 var panEnd = new Vector2(); 55227 var panDelta = new Vector2(); 55228 55229 var dollyStart = new Vector2(); 55230 var dollyEnd = new Vector2(); 55231 var dollyDelta = new Vector2(); 55232 55233 function getAutoRotationAngle() { 55234 55235 return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; 55236 55237 } 55238 55239 function getZoomScale() { 55240 55241 return Math.pow( 0.95, scope.zoomSpeed ); 55242 55243 } 55244 55245 scope.rotateLeft = function( angle ) { 55246 55247 sphericalDelta.theta -= angle; 55248 55249 }; 55250 55251 scope.rotateUp = function( angle ) { 55252 55253 sphericalDelta.phi -= angle; 55254 55255 }; 55256 55257 var panLeft = function () { 55258 55259 var v = new Vector3(); 55260 55261 return function panLeft( distance, objectMatrix ) { 55262 55263 v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix 55264 v.multiplyScalar( - distance ); 55265 55266 panOffset.add( v ); 55267 55268 }; 55269 55270 }(); 55271 55272 var panUp = function () { 55273 55274 var v = new Vector3(); 55275 55276 return function panUp( distance, objectMatrix ) { 55277 55278 if ( scope.screenSpacePanning === true ) { 55279 55280 v.setFromMatrixColumn( objectMatrix, 1 ); 55281 55282 } else { 55283 55284 v.setFromMatrixColumn( objectMatrix, 0 ); 55285 v.crossVectors( scope.object.up, v ); 55286 55287 } 55288 55289 v.multiplyScalar( distance ); 55290 55291 panOffset.add( v ); 55292 55293 }; 55294 55295 }(); 55296 55297 // deltaX and deltaY are in pixels; right and down are positive 55298 var pan = function () { 55299 55300 var offset = new Vector3(); 55301 55302 return function pan( deltaX, deltaY ) { 55303 55304 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 55305 55306 if ( scope.object.isPerspectiveCamera ) { 55307 55308 // perspective 55309 var position = scope.object.position; 55310 offset.copy( position ).sub( scope.target ); 55311 var targetDistance = offset.length(); 55312 55313 // half of the fov is center to top of screen 55314 targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); 55315 55316 // we use only clientHeight here so aspect ratio does not distort speed 55317 panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); 55318 panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); 55319 55320 } else if ( scope.object.isOrthographicCamera ) { 55321 55322 // orthographic 55323 panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); 55324 panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); 55325 55326 } else { 55327 55328 // camera neither orthographic nor perspective 55329 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); 55330 scope.enablePan = false;
55331 55332 } 55333 55334 }; 55335 55336 }(); 55337 55338 function dollyIn( dollyScale ) { 55339 55340 if ( scope.object.isPerspectiveCamera ) { 55341 55342 scale /= dollyScale; 55343 55344 } else if ( scope.object.isOrthographicCamera ) { 55345 55346 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); 55347 scope.object.updateProjectionMatrix(); 55348 zoomChanged = true; 55349 55350 } else { 55351 55352 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); 55353 scope.enableZoom = false; 55354 55355 } 55356 55357 } 55358 55359 function dollyOut( dollyScale ) { 55360 55361 if ( scope.object.isPerspectiveCamera ) { 55362 55363 scale *= dollyScale; 55364 55365 } else if ( scope.object.isOrthographicCamera ) { 55366 55367 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); 55368 scope.object.updateProjectionMatrix(); 55369 zoomChanged = true; 55370 55371 } else { 55372 55373 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); 55374 scope.enableZoom = false;
vendor: 14,089 bytes, lines 55375-56053
55375 55376 } 55377 55378 } 55379 55380 // 55381 // event callbacks - update the object state 55382 // 55383 55384 function handleMouseDownRotate( event ) { 55385 55386 //console.log( 'handleMouseDownRotate' ); 55387 55388 rotateStart.set( event.clientX, event.clientY ); 55389 55390 } 55391 55392 function handleMouseDownDolly( event ) { 55393 55394 //console.log( 'handleMouseDownDolly' ); 55395 55396 dollyStart.set( event.clientX, event.clientY ); 55397 55398 } 55399 55400 function handleMouseDownPan( event ) { 55401 55402 //console.log( 'handleMouseDownPan' ); 55403 55404 panStart.set( event.clientX, event.clientY ); 55405 55406 } 55407 55408 function handleMouseMoveRotate( event ) { 55409 55410 //console.log( 'handleMouseMoveRotate' ); 55411 55412 rotateEnd.set( event.clientX, event.clientY ); 55413 55414 rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); 55415 55416 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 55417 55418 scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height 55419 55420 scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); 55421 55422 rotateStart.copy( rotateEnd ); 55423 55424 scope.update(); 55425 55426 } 55427 55428 function handleMouseMoveDolly( event ) { 55429 55430 //console.log( 'handleMouseMoveDolly' ); 55431 55432 dollyEnd.set( event.clientX, event.clientY ); 55433 55434 dollyDelta.subVectors( dollyEnd, dollyStart ); 55435 55436 if ( dollyDelta.y > 0 ) { 55437 55438 dollyIn( getZoomScale() ); 55439 55440 } else if ( dollyDelta.y < 0 ) { 55441 55442 dollyOut( getZoomScale() ); 55443 55444 } 55445 55446 dollyStart.copy( dollyEnd ); 55447 55448 scope.update(); 55449 55450 } 55451 55452 function handleMouseMovePan( event ) { 55453 55454 //console.log( 'handleMouseMovePan' ); 55455 55456 panEnd.set( event.clientX, event.clientY ); 55457 55458 panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); 55459 55460 pan( panDelta.x, panDelta.y ); 55461 55462 panStart.copy( panEnd ); 55463 55464 scope.update(); 55465 55466 } 55467 55468 function handleMouseWheel( event ) { 55469 55470 // console.log( 'handleMouseWheel' ); 55471 55472 if ( event.deltaY < 0 ) { 55473 55474 dollyOut( getZoomScale() ); 55475 55476 } else if ( event.deltaY > 0 ) { 55477 55478 dollyIn( getZoomScale() ); 55479 55480 } 55481 55482 scope.update(); 55483 55484 } 55485 55486 function handleKeyDown( event ) { 55487 55488 //console.log( 'handleKeyDown' ); 55489 55490 switch ( event.keyCode ) { 55491 55492 case scope.keys.UP: 55493 pan( 0, scope.keyPanSpeed ); 55494 scope.update(); 55495 break; 55496 55497 case scope.keys.BOTTOM: 55498 pan( 0, - scope.keyPanSpeed ); 55499 scope.update(); 55500 break; 55501 55502 case scope.keys.LEFT: 55503 pan( scope.keyPanSpeed, 0 ); 55504 scope.update(); 55505 break; 55506 55507 case scope.keys.RIGHT: 55508 pan( - scope.keyPanSpeed, 0 ); 55509 scope.update(); 55510 break; 55511 55512 } 55513 55514 } 55515 55516 function handleTouchStartRotate( event ) { 55517 55518 //console.log( 'handleTouchStartRotate' ); 55519 55520 rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 55521 55522 } 55523 55524 function handleTouchStartDollyPan( event ) { 55525 55526 //console.log( 'handleTouchStartDollyPan' ); 55527 55528 if ( scope.enableZoom ) { 55529 55530 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 55531 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 55532 55533 var distance = Math.sqrt( dx * dx + dy * dy ); 55534 55535 dollyStart.set( 0, distance ); 55536 55537 } 55538 55539 if ( scope.enablePan ) { 55540 55541 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); 55542 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); 55543 55544 panStart.set( x, y ); 55545 55546 } 55547 55548 } 55549 55550 function handleTouchMoveRotate( event ) { 55551 55552 //console.log( 'handleTouchMoveRotate' ); 55553 55554 rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 55555 55556 rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); 55557 55558 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 55559 55560 scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height 55561 55562 scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); 55563 55564 rotateStart.copy( rotateEnd ); 55565 55566 scope.update(); 55567 55568 } 55569 55570 function handleTouchMoveDollyPan( event ) { 55571 55572 //console.log( 'handleTouchMoveDollyPan' ); 55573 55574 if ( scope.enableZoom ) { 55575 55576 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 55577 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 55578 55579 var distance = Math.sqrt( dx * dx + dy * dy ); 55580 55581 dollyEnd.set( 0, distance ); 55582 55583 dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); 55584 55585 dollyIn( dollyDelta.y ); 55586 55587 dollyStart.copy( dollyEnd ); 55588 55589 } 55590 55591 if ( scope.enablePan ) { 55592 55593 var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); 55594 var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); 55595 55596 panEnd.set( x, y ); 55597 55598 panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); 55599 55600 pan( panDelta.x, panDelta.y ); 55601 55602 panStart.copy( panEnd ); 55603 55604 } 55605 55606 scope.update(); 55607 55608 } 55609 55610 // 55611 // event handlers - FSM: listen for events and reset state 55612 // 55613 55614 function onMouseDown( event ) { 55615 55616 if ( scope.enabled === false ) return; 55617 55618 event.preventDefault(); 55619 55620 switch ( event.button ) { 55621 55622 case scope.mouseButtons.ORBIT: 55623 55624 if ( scope.enableRotate === false ) return; 55625 55626 handleMouseDownRotate( event ); 55627 55628 state = STATE.ROTATE; 55629 55630 break; 55631 55632 case scope.mouseButtons.ZOOM: 55633 55634 if ( scope.enableZoom === false ) return; 55635 55636 handleMouseDownDolly( event ); 55637 55638 state = STATE.DOLLY; 55639 55640 break; 55641 55642 case scope.mouseButtons.PAN: 55643 55644 if ( scope.enablePan === false ) return; 55645 55646 handleMouseDownPan( event ); 55647 55648 state = STATE.PAN; 55649 55650 break; 55651 55652 } 55653 55654 if ( state !== STATE.NONE ) { 55655 55656 document.addEventListener( 'mousemove', onMouseMove, false ); 55657 document.addEventListener( 'mouseup', onMouseUp, false ); 55658 55659 scope.dispatchEvent( startEvent ); 55660 55661 } 55662 55663 } 55664 55665 function onMouseMove( event ) { 55666 55667 if ( scope.enabled === false ) return; 55668 55669 event.preventDefault(); 55670 55671 switch ( state ) { 55672 55673 case STATE.ROTATE: 55674 55675 if ( scope.enableRotate === false ) return; 55676 55677 handleMouseMoveRotate( event ); 55678 55679 break; 55680 55681 case STATE.DOLLY: 55682 55683 if ( scope.enableZoom === false ) return; 55684 55685 handleMouseMoveDolly( event ); 55686 55687 break; 55688 55689 case STATE.PAN: 55690 55691 if ( scope.enablePan === false ) return; 55692 55693 handleMouseMovePan( event ); 55694 55695 break; 55696 55697 } 55698 55699 } 55700 55701 function onMouseUp( event ) { 55702 55703 if ( scope.enabled === false ) return; 55704 55705 document.removeEventListener( 'mousemove', onMouseMove, false ); 55706 document.removeEventListener( 'mouseup', onMouseUp, false ); 55707 55708 scope.dispatchEvent( endEvent ); 55709 55710 state = STATE.NONE; 55711 55712 } 55713 55714 function onMouseWheel( event ) { 55715 55716 if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; 55717 55718 event.preventDefault(); 55719 event.stopPropagation(); 55720 55721 scope.dispatchEvent( startEvent ); 55722 55723 handleMouseWheel( event ); 55724 55725 scope.dispatchEvent( endEvent ); 55726 55727 } 55728 55729 function onKeyDown( event ) { 55730 55731 if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; 55732 55733 handleKeyDown( event ); 55734 55735 } 55736 55737 function onTouchStart( event ) { 55738 55739 if ( scope.enabled === false ) return; 55740 55741 event.preventDefault(); 55742 55743 switch ( event.touches.length ) { 55744 55745 case 1: // one-fingered touch: rotate 55746 55747 if ( scope.enableRotate === false ) return; 55748 55749 handleTouchStartRotate( event ); 55750 55751 state = STATE.TOUCH_ROTATE; 55752 55753 break; 55754 55755 case 2: // two-fingered touch: dolly-pan 55756 55757 if ( scope.enableZoom === false && scope.enablePan === false ) return; 55758 55759 handleTouchStartDollyPan( event ); 55760 55761 state = STATE.TOUCH_DOLLY_PAN; 55762 55763 break; 55764 55765 default: 55766 55767 state = STATE.NONE; 55768 55769 } 55770 55771 if ( state !== STATE.NONE ) { 55772 55773 scope.dispatchEvent( startEvent ); 55774 55775 } 55776 55777 } 55778 55779 function onTouchMove( event ) { 55780 55781 if ( scope.enabled === false ) return; 55782 55783 event.preventDefault(); 55784 event.stopPropagation(); 55785 55786 switch ( event.touches.length ) { 55787 55788 case 1: // one-fingered touch: rotate 55789 55790 if ( scope.enableRotate === false ) return; 55791 if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed? 55792 55793 handleTouchMoveRotate( event ); 55794 55795 break; 55796 55797 case 2: // two-fingered touch: dolly-pan 55798 55799 if ( scope.enableZoom === false && scope.enablePan === false ) return; 55800 if ( state !== STATE.TOUCH_DOLLY_PAN ) return; // is this needed? 55801 55802 handleTouchMoveDollyPan( event ); 55803 55804 break; 55805 55806 default: 55807 55808 state = STATE.NONE; 55809 55810 } 55811 55812 } 55813 55814 function onTouchEnd( event ) { 55815 55816 if ( scope.enabled === false ) return; 55817 55818 scope.dispatchEvent( endEvent ); 55819 55820 state = STATE.NONE; 55821 55822 } 55823 55824 function onContextMenu( event ) { 55825 55826 if ( scope.enabled === false ) return; 55827 55828 event.preventDefault(); 55829 55830 } 55831 55832 // 55833 55834 //scope.domElement.addEventListener\( 'contextmenu', onContextMenu, false ); 55835 55836 scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); 55837 scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); 55838 55839 scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); 55840 scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); 55841 scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); 55842 55843 window.addEventListener( 'keydown', onKeyDown, false ); 55844 55845 // force an update at start 55846 55847 this.update(); 55848 55849 }; 55850 55851 OrbitControls.prototype = Object.create( EventDispatcher.prototype ); 55852 OrbitControls.prototype.constructor = OrbitControls; 55853 55854 Object.defineProperties( OrbitControls.prototype, { 55855 55856 center: { 55857 55858 get: function () { 55859 55860 console.warn( 'OrbitControls: .center has been renamed to .target' ); 55861 return this.target; 55862 55863 } 55864 55865 }, 55866 55867 // backward compatibility 55868 55869 noZoom: { 55870 55871 get: function () { 55872 55873 console.warn( 'OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 55874 return ! this.enableZoom; 55875 55876 }, 55877 55878 set: function ( value ) { 55879 55880 console.warn( 'OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 55881 this.enableZoom = ! value; 55882 55883 } 55884 55885 }, 55886 55887 noRotate: { 55888 55889 get: function () { 55890 55891 console.warn( 'OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 55892 return ! this.enableRotate; 55893 55894 }, 55895 55896 set: function ( value ) { 55897 55898 console.warn( 'OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 55899 this.enableRotate = ! value; 55900 55901 } 55902 55903 }, 55904 55905 noPan: { 55906 55907 get: function () { 55908 55909 console.warn( 'OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 55910 return ! this.enablePan; 55911 55912 }, 55913 55914 set: function ( value ) { 55915 55916 console.warn( 'OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 55917 this.enablePan = ! value; 55918 55919 } 55920 55921 }, 55922 55923 noKeys: { 55924 55925 get: function () { 55926 55927 console.warn( 'OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 55928 return ! this.enableKeys; 55929 55930 }, 55931 55932 set: function ( value ) { 55933 55934 console.warn( 'OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 55935 this.enableKeys = ! value; 55936 55937 } 55938 55939 }, 55940 55941 staticMoving: { 55942 55943 get: function () { 55944 55945 console.warn( 'OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 55946 return ! this.enableDamping; 55947 55948 }, 55949 55950 set: function ( value ) { 55951 55952 console.warn( 'OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 55953 this.enableDamping = ! value; 55954 55955 } 55956 55957 }, 55958 55959 dynamicDampingFactor: { 55960 55961 get: function () { 55962 55963 console.warn( 'OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 55964 return this.dampingFactor; 55965 55966 }, 55967 55968 set: function ( value ) { 55969 55970 console.warn( 'OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 55971 this.dampingFactor = value; 55972 55973 } 55974 55975 } 55976 55977 } ); 55978 55979 /** 55980 * @author richt / http://richt.me 55981 * @author WestLangley / http://github.com/WestLangley 55982 * 55983 * W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html) 55984 */ 55985 var DeviceOrientationControls = function ( object ) { 55986 55987 var scope = this; 55988 55989 this.object = object; 55990 this.object.rotation.reorder( 'YXZ' ); 55991 55992 this.enabled = true; 55993 55994 this.deviceOrientation = {}; 55995 this.screenOrientation = 0; 55996 55997 this.alphaOffset = 0; // radians 55998 55999 var onDeviceOrientationChangeEvent = function ( event ) { 56000 56001 scope.deviceOrientation = event; 56002 56003 }; 56004 56005 var onScreenOrientationChangeEvent = function () { 56006 56007 scope.screenOrientation = window.orientation || 0; 56008 56009 }; 56010 56011 // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y'' 56012 56013 var setObjectQuaternion = function () { 56014 56015 var zee = new Vector3( 0, 0, 1 ); 56016 56017 var euler = new Euler(); 56018 56019 var q0 = new Quaternion(); 56020 56021 var q1 = new Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis 56022 56023 return function ( quaternion, alpha, beta, gamma, orient ) { 56024 56025 euler.set( beta, alpha, - gamma, 'YXZ' ); // 'ZXY' for the device, but 'YXZ' for us 56026 56027 quaternion.setFromEuler( euler ); // orient the device 56028 56029 quaternion.multiply( q1 ); // camera looks out the back of the device, not the top 56030 56031 quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation 56032 56033 }; 56034 56035 }(); 56036 56037 this.connect = function () { 56038 56039 onScreenOrientationChangeEvent(); // run once on load 56040 56041 window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false ); 56042 window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false ); 56043 56044 scope.enabled = true; 56045 56046 }; 56047 56048 this.disconnect = function () { 56049 56050 window.removeEventListener( 'orientationchange', onScreenOrientationChangeEvent, false ); 56051 window.removeEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false ); 56052 56053 scope.enabled = false;
vendor: 1,895 bytes, lines 56054-56137
56054 56055 }; 56056 56057 this.update = function () { 56058 56059 if ( scope.enabled === false ) return; 56060 56061 var device = scope.deviceOrientation; 56062 56063 if ( device ) { 56064 56065 var alpha = device.alpha ? _Math.degToRad( device.alpha ) + scope.alphaOffset : 0; // Z 56066 56067 var beta = device.beta ? _Math.degToRad( device.beta ) : 0; // X' 56068 56069 var gamma = device.gamma ? _Math.degToRad( device.gamma ) : 0; // Y'' 56070 56071 var orient = scope.screenOrientation ? _Math.degToRad( scope.screenOrientation ) : 0; // O 56072 56073 setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient ); 56074 56075 } 56076 56077 56078 }; 56079 56080 this.dispose = function () { 56081 56082 scope.disconnect(); 56083 56084 }; 56085 56086 this.connect(); 56087 56088 }; 56089 56090 /** 56091 * Convert a quaternion to an angle 56092 * 56093 * Taken from https://stackoverflow.com/a/35448946 56094 * Thanks P. Ellul 56095 */ 56096 56097 function Quat2Angle(x, y, z, w) { 56098 var test = x * y + z * w; // singularity at north pole 56099 56100 if (test > 0.499) { 56101 var _yaw = 2 * Math.atan2(x, w); 56102 56103 var _pitch = Math.PI / 2; 56104 56105 var _roll = 0; 56106 return new Vector3(_pitch, _roll, _yaw); 56107 } // singularity at south pole 56108 56109 56110 if (test < -0.499) { 56111 var _yaw2 = -2 * Math.atan2(x, w); 56112 56113 var _pitch2 = -Math.PI / 2; 56114 56115 var _roll2 = 0; 56116 return new Vector3(_pitch2, _roll2, _yaw2); 56117 } 56118 56119 var sqx = x * x; 56120 var sqy = y * y; 56121 var sqz = z * z; 56122 var yaw = Math.atan2(2 * y * w - 2 * x * z, 1 - 2 * sqy - 2 * sqz); 56123 var pitch = Math.asin(2 * test); 56124 var roll = Math.atan2(2 * x * w - 2 * y * z, 1 - 2 * sqx - 2 * sqz); 56125 return new Vector3(pitch, roll, yaw); 56126 } 56127 56128 var OrbitOrientationControls = 56129 /*#__PURE__*/ 56130 function () { 56131 function OrbitOrientationControls(options) { 56132 this.object = options.camera; 56133 this.domElement = options.canvas; 56134 this.orbit = new OrbitControls(this.object, this.domElement); 56135 this.speed = 0.5; 56136 this.orbit.target.set(0, 0, -1); 56137 this.orbit.enableZoom = false;
56138 this.orbit.enablePan = false; 56139 this.orbit.rotateSpeed = -this.speed; // if orientation is supported 56140 56141 if (options.orientation) { 56142 this.orientation = new DeviceOrientationControls(this.object); 56143 } // if projection is not full view 56144 // limit the rotation angle in order to not display back half view 56145 56146 56147 if (options.halfView) { 56148 this.orbit.minAzimuthAngle = -Math.PI / 4; 56149 this.orbit.maxAzimuthAngle = Math.PI / 4; 56150 } 56151 } 56152 56153 var _proto = OrbitOrientationControls.prototype; 56154 56155 _proto.update = function update() { 56156 // orientation updates the camera using quaternions and 56157 // orbit updates the camera using angles. They are incompatible 56158 // and one update overrides the other. So before 56159 // orbit overrides orientation we convert our quaternion changes to 56160 // an angle change. Then save the angle into orbit so that 56161 // it will take those into account when it updates the camera and overrides 56162 // our changes 56163 if (this.orientation) { 56164 this.orientation.update(); 56165 var quat = this.orientation.object.quaternion; 56166 var currentAngle = Quat2Angle(quat.x, quat.y, quat.z, quat.w); // we also have to store the last angle since quaternions are b 56167 56168 if (typeof this.lastAngle_ === 'undefined') { 56169 this.lastAngle_ = currentAngle; 56170 } 56171 56172 this.orbit.rotateLeft((this.lastAngle_.z - currentAngle.z) * (1 + this.speed)); 56173 this.orbit.rotateUp((this.lastAngle_.y - currentAngle.y) * (1 + this.speed)); 56174 this.lastAngle_ = currentAngle; 56175 } 56176 56177 this.orbit.update(); 56178 }; 56179 56180 _proto.dispose = function dispose() { 56181 this.orbit.dispose(); 56182 56183 if (this.orientation) { 56184 this.orientation.dispose(); 56185 } 56186 }; 56187 56188 return OrbitOrientationControls; 56189 }(); 56190 56191 var corsSupport = function () { 56192 var video = document$1.createElement('video'); 56193 video.crossOrigin = 'anonymous'; 56194 return video.hasAttribute('crossorigin'); 56195 }(); 56196 var validProjections = ['360', '360_LR', '360_TB', '360_CUBE', 'EAC', 'EAC_LR', 'NONE', 'AUTO', 'Sphere', 'Cube', 'equirectangular', '180', '180_LR', '180_MONO']; 56197 var getInternalProjectionName = function getInternalProjectionName(projection) { 56198 if (!projection) { 56199 return; 56200 } 56201 56202 projection = projection.toString().trim(); 56203 56204 if (/sphere/i.test(projection)) { 56205 return '360'; 56206 } 56207 56208 if (/cube/i.test(projection)) { 56209 return '360_CUBE'; 56210 } 56211 56212 if (/equirectangular/i.test(projection)) { 56213 return '360'; 56214 } 56215 56216 for (var i = 0; i < validProjections.length; i++) { 56217 if (new RegExp('^' + validProjections[i] + '$', 'i').test(projection)) { 56218 return validProjections[i]; 56219 } 56220 } 56221 }; 56222 56223 /** 56224 * This class reacts to interactions with the canvas and 56225 * triggers appropriate functionality on the player. Right now 56226 * it does two things: 56227 * 56228 * 1. A `mousedown`/`touchstart` followed by `touchend`/`mouseup` without any 56229 * `touchmove` or `mousemove` toggles play/pause on the player 56230 * 2. Only moving on/clicking the control bar or toggling play/pause should 56231 * show the control bar. Moving around the scene in the canvas should not. 56232 */ 56233 56234 var CanvasPlayerControls = 56235 /*#__PURE__*/ 56236 function (_videojs$EventTarget) { 56237 inheritsLoose(CanvasPlayerControls, _videojs$EventTarget); 56238 56239 function CanvasPlayerControls(player, canvas) { 56240 var _this; 56241 56242 _this = _videojs$EventTarget.call(this) || this; 56243 _this.player = player; 56244 _this.canvas = canvas; 56245 _this.onMoveEnd = videojs.bind(assertThisInitialized(_this), _this.onMoveEnd); 56246 _this.onMoveStart = videojs.bind(assertThisInitialized(_this), _this.onMoveStart); 56247 _this.onMove = videojs.bind(assertThisInitialized(_this), _this.onMove); 56248 _this.onControlBarMove = videojs.bind(assertThisInitialized(_this), _this.onControlBarMove); 56249 56250 _this.player.controlBar.on(['mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend'], _this.onControlBarMove); // we have to override these here because 56251 // video.js listens for user activity on the video element 56252 // and makes the user active when the mouse moves. 56253 // We don't want that for 3d videos 56254 56255 56256 _this.oldReportUserActivity = _this.player.reportUserActivity; 56257 56258 _this.player.reportUserActivity = function () {}; // canvas movements 56259 56260 56261 _this.canvas.addEventListener('mousedown', _this.onMoveStart); 56262 56263 _this.canvas.addEventListener('touchstart', _this.onMoveStart); 56264 56265 _this.canvas.addEventListener('mousemove', _this.onMove); 56266 56267 _this.canvas.addEventListener('touchmove', _this.onMove); 56268 56269 _this.canvas.addEventListener('mouseup', _this.onMoveEnd); 56270 56271 _this.canvas.addEventListener('touchend', _this.onMoveEnd); 56272 56273 _this.shouldTogglePlay = false;
56274 return _this; 56275 } 56276 56277 var _proto = CanvasPlayerControls.prototype; 56278 56279 _proto.togglePlay = function togglePlay() { 56280 if (this.player.paused()) { 56281 this.player.play(); 56282 } else { 56283 this.player.pause(); 56284 } 56285 }; 56286 56287 _proto.onMoveStart = function onMoveStart(e) { 56288 // if the player does not have a controlbar or 56289 // the move was a mouse click but not left click do not 56290 // toggle play. 56291 if (!this.player.controls() || e.type === 'mousedown' && !videojs.dom.isSingleLeftClick(e)) { 56292 this.shouldTogglePlay = false; 56293 return; 56294 } 56295 56296 this.shouldTogglePlay = true; 56297 this.touchMoveCount_ = 0; 56298 }; 56299 56300 _proto.onMoveEnd = function onMoveEnd(e) { 56301 // We want to have the same behavior in VR360 Player and standard player. 56302 // in touchend we want to know if was a touch click, for a click we show the bar, 56303 // otherwise continue with the mouse logic. 56304 // 56305 // Maximum movement allowed during a touch event to still be considered a tap 56306 // Other popular libs use anywhere from 2 (hammer.js) to 15, 56307 // so 10 seems like a nice, round number. 56308 if (e.type === 'touchend' && this.touchMoveCount_ < 10) { 56309 if (this.player.userActive() === false) { 56310 this.player.userActive(true); 56311 return; 56312 } 56313 56314 this.player.userActive(false); 56315 return; 56316 } 56317 56318 if (!this.shouldTogglePlay) { 56319 return; 56320 } // We want the same behavior in Desktop for VR360 and standard player 56321 56322 56323 if (e.type == 'mouseup') { 56324 this.togglePlay(); 56325 } 56326 }; 56327 56328 _proto.onMove = function onMove(e) { 56329 // Increase touchMoveCount_ since Android detects 1 - 6 touches when user click normally 56330 this.touchMoveCount_++; 56331 this.shouldTogglePlay = false; 56332 }; 56333 56334 _proto.onControlBarMove = function onControlBarMove(e) { 56335 this.player.userActive(true); 56336 }; 56337 56338 _proto.dispose = function dispose() { 56339 this.canvas.removeEventListener('mousedown', this.onMoveStart); 56340 this.canvas.removeEventListener('touchstart', this.onMoveStart); 56341 this.canvas.removeEventListener('mousemove', this.onMove); 56342 this.canvas.removeEventListener('touchmove', this.onMove); 56343 this.canvas.removeEventListener('mouseup', this.onMoveEnd); 56344 this.canvas.removeEventListener('touchend', this.onMoveEnd); 56345 this.player.controlBar.off(['mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend'], this.onControlBarMove); 56346 this.player.reportUserActivity = this.oldReportUserActivity; 56347 }; 56348 56349 return CanvasPlayerControls; 56350 }(videojs.EventTarget); 56351 56352 /** 56353 * This class manages ambisonic decoding and binaural rendering via Omnitone library. 56354 */ 56355 56356 var OmnitoneController = 56357 /*#__PURE__*/ 56358 function (_videojs$EventTarget) { 56359 inheritsLoose(OmnitoneController, _videojs$EventTarget); 56360 56361 /** 56362 * Omnitone controller class. 56363 * 56364 * @class 56365 * @param {AudioContext} audioContext - associated AudioContext. 56366 * @param {Omnitone library} omnitone - Omnitone library element. 56367 * @param {HTMLVideoElement} video - vidoe tag element. 56368 * @param {Object} options - omnitone options. 56369 */ 56370 function OmnitoneController(audioContext, omnitone, video, options) { 56371 var _this; 56372 56373 _this = _videojs$EventTarget.call(this) || this; 56374 var settings = videojs.mergeOptions({ 56375 // Safari uses the different AAC decoder than FFMPEG. The channel order is 56376 // The default 4ch AAC channel layout for FFMPEG AAC channel ordering. 56377 channelMap: videojs.browser.IS_SAFARI ? [2, 0, 1, 3] : [0, 1, 2, 3], 56378 ambisonicOrder: 1 56379 }, options); 56380 _this.videoElementSource = audioContext.createMediaElementSource(video); 56381 _this.foaRenderer = omnitone.createFOARenderer(audioContext, settings); 56382 56383 _this.foaRenderer.initialize().then(function () { 56384 if (audioContext.state === 'suspended') { 56385 _this.trigger({ 56386 type: 'audiocontext-suspended' 56387 }); 56388 } 56389 56390 _this.videoElementSource.connect(_this.foaRenderer.input); 56391 56392 _this.foaRenderer.output.connect(audioContext.destination); 56393 56394 _this.initialized = true; 56395 56396 _this.trigger({ 56397 type: 'omnitone-ready' 56398 }); 56399 }, function (error) { 56400 videojs.log.warn("videojs-vr: Omnitone initializes failed with the following error: " + error + ")"); 56401 }); 56402 56403 return _this; 56404 } 56405 /** 56406 * Updates the rotation of the Omnitone decoder based on three.js camera matrix. 56407 * 56408 * @param {Camera} camera Three.js camera object 56409 */ 56410 56411 56412 var _proto = OmnitoneController.prototype; 56413 56414 _proto.update = function update(camera) { 56415 if (!this.initialized) { 56416 return; 56417 } 56418
56419 this.foaRenderer.setRotationMatrixFromCamera(camera.matrix); 56420 } 56421 /** 56422 * Destroys the controller and does any necessary cleanup. 56423 */ 56424 ; 56425 56426 _proto.dispose = function dispose() { 56427 this.initialized = false; 56428 this.foaRenderer.setRenderingMode('bypass'); 56429 this.foaRenderer = null; 56430 }; 56431 56432 return OmnitoneController; 56433 }(videojs.EventTarget); 56434 56435 var Button = videojs.getComponent('Button'); 56436 56437 var CardboardButton = 56438 /*#__PURE__*/ 56439 function (_Button) { 56440 inheritsLoose(CardboardButton, _Button); 56441 56442 function CardboardButton(player, options) { 56443 var _this; 56444 56445 _this = _Button.call(this, player, options) || this; 56446 _this.handleVrDisplayActivate_ = videojs.bind(assertThisInitialized(_this), _this.handleVrDisplayActivate_); 56447 _this.handleVrDisplayDeactivate_ = videojs.bind(assertThisInitialized(_this), _this.handleVrDisplayDeactivate_); 56448 _this.handleVrDisplayPresentChange_ = videojs.bind(assertThisInitialized(_this), _this.handleVrDisplayPresentChange_); 56449 _this.handleOrientationChange_ = videojs.bind(assertThisInitialized(_this), _this.handleOrientationChange_); 56450 window$1.addEventListener('orientationchange', _this.handleOrientationChange_); 56451 window$1.addEventListener('vrdisplayactivate', _this.handleVrDisplayActivate_); 56452 window$1.addEventListener('vrdisplaydeactivate', _this.handleVrDisplayDeactivate_); // vrdisplaypresentchange does not fire activate or deactivate 56453 // and happens when hitting the back button during cardboard mode 56454 // so we need to make sure we stay in the correct state by 56455 // listening to it and checking if we are presenting it or not 56456 56457 window$1.addEventListener('vrdisplaypresentchange', _this.handleVrDisplayPresentChange_); // we cannot show the cardboard button in fullscreen on 56458 // android as it breaks the controls, and makes it impossible 56459 // to exit cardboard mode 56460 56461 if (videojs.browser.IS_ANDROID) { 56462 _this.on(player, 'fullscreenchange', function () { 56463 if (player.isFullscreen()) { 56464 _this.hide(); 56465 } else { 56466 _this.show(); 56467 } 56468 }); 56469 } 56470 56471 return _this; 56472 } 56473 56474 var _proto = CardboardButton.prototype; 56475 56476 _proto.buildCSSClass = function buildCSSClass() { 56477 return "vjs-button-vr " + _Button.prototype.buildCSSClass.call(this); 56478 }; 56479 56480 _proto.handleVrDisplayPresentChange_ = function handleVrDisplayPresentChange_() { 56481 if (!this.player_.vr().vrDisplay.isPresenting && this.active_) { 56482 this.handleVrDisplayDeactivate_(); 56483 } 56484 56485 if (this.player_.vr().vrDisplay.isPresenting && !this.active_) { 56486 this.handleVrDisplayActivate_(); 56487 } 56488 }; 56489 56490 _proto.handleOrientationChange_ = function handleOrientationChange_() { 56491 if (this.active_ && videojs.browser.IS_IOS) { 56492 this.changeSize_(); 56493 } 56494 }; 56495 56496 _proto.changeSize_ = function changeSize_() { 56497 this.player_.width(window$1.innerWidth); 56498 this.player_.height(window$1.innerHeight); 56499 window$1.dispatchEvent(new window$1.Event('resize')); 56500 }; 56501 56502 _proto.handleVrDisplayActivate_ = function handleVrDisplayActivate_() { 56503 // we mimic fullscreen on IOS 56504 if (videojs.browser.IS_IOS) { 56505 this.oldWidth_ = this.player_.currentWidth(); 56506 this.oldHeight_ = this.player_.currentHeight(); 56507 this.player_.enterFullWindow(); 56508 this.changeSize_(); 56509 } 56510 56511 this.active_ = true; 56512 }; 56513 56514 _proto.handleVrDisplayDeactivate_ = function handleVrDisplayDeactivate_() { 56515 // un-mimic fullscreen on iOS 56516 if (videojs.browser.IS_IOS) { 56517 if (this.oldWidth_) { 56518 this.player_.width(this.oldWidth_); 56519 } 56520 56521 if (this.oldHeight_) { 56522 this.player_.height(this.oldHeight_); 56523 } 56524 56525 this.player_.exitFullWindow(); 56526 } 56527 56528 this.active_ = false; 56529 }; 56530 56531 _proto.handleClick = function handleClick(event) { 56532 // if cardboard mode display is not active, activate it 56533 // otherwise deactivate it 56534 if (!this.active_) { 56535 // This starts playback mode when the cardboard button 56536 // is clicked on Android. We need to do this as the controls 56537 // disappear 56538 if (!this.player_.hasStarted() && videojs.browser.IS_ANDROID) { 56539 this.player_.play(); 56540 } 56541 56542 window$1.dispatchEvent(new window$1.Event('vrdisplayactivate')); 56543 } else { 56544 window$1.dispatchEvent(new window$1.Event('vrdisplaydeactivate')); 56545 } 56546 }; 56547 56548 _proto.dispose = function dispose() { 56549 _Button.prototype.dispose.call(this); 56550 56551 window$1.removeEventListener('vrdisplayactivate', this.handleVrDisplayActivate_); 56552 window$1.removeEventListener('vrdisplaydeactivate', this.handleVrDisplayDeactivate_); 56553 window$1.removeEventListener('vrdisplaypresentchange', this.handleVrDisplayPresentChange_); 56554 }; 56555 56556 return CardboardButton; 56557 }(Button); 56558 56559 videojs.registerComponent('CardboardButton', CardboardButton); 56560 56561 var BigPlayButton = videojs.getComponent('BigPlayButton'); 56562 56563 var BigVrPlayButton = 56564 /*#__PURE__*/ 56565 function (_BigPlayButton) { 56566 inheritsLoose(BigVrPlayButton, _BigPlayButton); 56567 56568 function BigVrPlayButton() { 56569 return _BigPlayButton.apply(this, arguments) || this; 56570 } 56571 56572 var _proto = BigVrPlayButton.prototype; 56573 56574 _proto.buildCSSClass = function buildCSSClass() { 56575 return "vjs-big-vr-play-button " + _BigPlayButton.prototype.buildCSSClass.call(this); 56576 }; 56577 56578 return BigVrPlayButton; 56579 }(BigPlayButton); 56580 56581 videojs.registerComponent('BigVrPlayButton', BigVrPlayButton); 56582 56583 var defaults = { 56584 debug: false, 56585 omnitone: false, 56586 forceCardboard: false, 56587 omnitoneOptions: {}, 56588 projection: 'AUTO', 56589 sphereDetail: 32 56590 }; 56591 var errors = { 56592 'web-vr-out-of-date': { 56593 headline: '360 is out of date', 56594 type: '360_OUT_OF_DATE', 56595 message: "Your browser supports 360 but not the latest version. See <a href='http://webvr.info'>http://webvr.info</a> for more info." 56596 }, 56597 'web-vr-not-supported': { 56598 headline: '360 not supported on this device', 56599 type: '360_NOT_SUPPORTED', 56600 message: "Your browser does not support 360. See <a href='http://webvr.info'>http://webvr.info</a> for assistance." 56601 }, 56602 'web-vr-hls-cors-not-supported': { 56603 headline: '360 HLS video not supported on this device', 56604 type: '360_NOT_SUPPORTED', 56605 message: "Your browser/device does not support HLS 360 video. See <a href='http://webvr.info'>http://webvr.info</a> for assistance." 56606 } 56607 }; 56608 var Plugin = videojs.getPlugin('plugin'); 56609 var Component = videojs.getComponent('Component'); 56610 56611 var VR = 56612 /*#__PURE__*/ 56613 function (_Plugin) { 56614 inheritsLoose(VR, _Plugin); 56615 56616 function VR(player, options) { 56617 var _this; 56618 56619 var settings = videojs.mergeOptions(defaults, options); 56620 _this = _Plugin.call(this, player, settings) || this; 56621 _this.options_ = settings; 56622 _this.player_ = player; 56623 _this.bigPlayButtonIndex_ = player.children().indexOf(player.getChild('BigPlayButton')) || 0; // custom videojs-errors integration boolean 56624 56625 _this.videojsErrorsSupport_ = !!videojs.errors; 56626 56627 if (_this.videojsErrorsSupport_) { 56628 player.errors({ 56629 errors: errors 56630 }); 56631 } // IE 11 does not support enough webgl to be supported 56632 // older safari does not support cors, so it wont work 56633 56634 56635 if (videojs.browser.IE_VERSION || !corsSupport) { 56636 // if a player triggers error before 'loadstart' is fired 56637 // video.js will reset the error overlay 56638 _this.player_.on('loadstart', function () { 56639 _this.triggerError_({ 56640 code: 'web-vr-not-supported',
56641 dismiss: false 56642 }); 56643 }); 56644 56645 return assertThisInitialized(_this); 56646 } 56647 56648 _this.polyfill_ = new WebVRPolyfill({ 56649 // do not show rotate instructions 56650 ROTATE_INSTRUCTIONS_DISABLED: true 56651 }); 56652 _this.polyfill_ = new WebVRPolyfill(); 56653 _this.handleVrDisplayActivate_ = videojs.bind(assertThisInitialized(_this), _this.handleVrDisplayActivate_); 56654 _this.handleVrDisplayDeactivate_ = videojs.bind(assertThisInitialized(_this), _this.handleVrDisplayDeactivate_); 56655 _this.handleResize_ = videojs.bind(assertThisInitialized(_this), _this.handleResize_); 56656 _this.animate_ = videojs.bind(assertThisInitialized(_this), _this.animate_); 56657 56658 _this.setProjection(_this.options_.projection); // any time the video element is recycled for ads 56659 // we have to reset the vr state and re-init after ad 56660 56661 56662 _this.on(player, 'adstart', function () { 56663 return player.setTimeout(function () { 56664 // if the video element was recycled for this ad 56665 if (!player.ads || !player.ads.videoElementRecycled()) { 56666 _this.log('video element not recycled for this ad, no need to reset'); 56667 56668 return; 56669 } 56670 56671 _this.log('video element recycled for this ad, reseting'); 56672 56673 _this.reset(); 56674 56675 _this.one(player, 'playing', _this.init); 56676 }); 56677 }, 1); 56678 56679 _this.on(player, 'loadedmetadata', _this.init); 56680 56681 return _this; 56682 } 56683 56684 var _proto = VR.prototype; 56685 56686 _proto.changeProjection_ = function changeProjection_(projection) { 56687 var _this2 = this; 56688 56689 projection = getInternalProjectionName(projection); // don't change to an invalid projection 56690 56691 if (!projection) { 56692 projection = 'NONE'; 56693 } 56694 56695 var position = { 56696 x: 0, 56697 y: 0, 56698 z: 0 56699 }; 56700 56701 if (this.scene) { 56702 this.scene.remove(this.movieScreen); 56703 } 56704 56705 if (projection === 'AUTO') { 56706 // mediainfo cannot be set to auto or we would infinite loop here 56707 // each source should know whatever they are 360 or not, if using AUTO 56708 if (this.player_.mediainfo && this.player_.mediainfo.projection && this.player_.mediainfo.projection !== 'AUTO') { 56709 var autoProjection = getInternalProjectionName(this.player_.mediainfo.projection); 56710 return this.changeProjection_(autoProjection); 56711 } 56712 56713 return this.changeProjection_('NONE'); 56714 } else if (projection === '360') { 56715 this.movieGeometry = new SphereBufferGeometry(256, this.options_.sphereDetail, this.options_.sphereDetail); 56716 this.movieMaterial = new MeshBasicMaterial({ 56717 map: this.videoTexture, 56718 overdraw: true, 56719 side: BackSide 56720 }); 56721 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); 56722 this.movieScreen.position.set(position.x, position.y, position.z); 56723 this.movieScreen.scale.x = -1; 56724 this.movieScreen.quaternion.setFromAxisAngle({ 56725 x: 0, 56726 y: 1, 56727 z: 0 56728 }, -Math.PI / 2); 56729 this.scene.add(this.movieScreen); 56730 } else if (projection === '360_LR' || projection === '360_TB') { 56731 // Left eye view 56732 var geometry = new SphereGeometry(256, this.options_.sphereDetail, this.options_.sphereDetail); 56733 var uvs = geometry.faceVertexUvs[0]; 56734 56735 for (var i = 0; i < uvs.length; i++) { 56736 for (var j = 0; j < 3; j++) { 56737 if (projection === '360_LR') { 56738 uvs[i][j].x *= 0.5; 56739 } else { 56740 uvs[i][j].y *= 0.5; 56741 uvs[i][j].y += 0.5; 56742 } 56743 } 56744 } 56745 56746 this.movieGeometry = new BufferGeometry().fromGeometry(geometry); 56747 this.movieMaterial = new MeshBasicMaterial({ 56748 map: this.videoTexture, 56749 overdraw: true, 56750 side: BackSide 56751 }); 56752 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); 56753 this.movieScreen.scale.x = -1; 56754 this.movieScreen.quaternion.setFromAxisAngle({ 56755 x: 0, 56756 y: 1, 56757 z: 0 56758 }, -Math.PI / 2); // display in left eye only 56759 56760 this.movieScreen.layers.set(1); 56761 this.scene.add(this.movieScreen); // Right eye view 56762 56763 geometry = new SphereGeometry(256, this.options_.sphereDetail, this.options_.sphereDetail); 56764 uvs = geometry.faceVertexUvs[0]; 56765 56766 for (var _i = 0; _i < uvs.length; _i++) { 56767 for (var _j = 0; _j < 3; _j++) { 56768 if (projection === '360_LR') { 56769 uvs[_i][_j].x *= 0.5; 56770 uvs[_i][_j].x += 0.5; 56771 } else { 56772 uvs[_i][_j].y *= 0.5; 56773 } 56774 } 56775 } 56776 56777 this.movieGeometry = new BufferGeometry().fromGeometry(geometry); 56778 this.movieMaterial = new MeshBasicMaterial({ 56779 map: this.videoTexture, 56780 overdraw: true, 56781 side: BackSide 56782 }); 56783 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); 56784 this.movieScreen.scale.x = -1; 56785 this.movieScreen.quaternion.setFromAxisAngle({ 56786 x: 0, 56787 y: 1, 56788 z: 0 56789 }, -Math.PI / 2); // display in right eye only 56790 56791 this.movieScreen.layers.set(2); 56792 this.scene.add(this.movieScreen); 56793 } else if (projection === '360_CUBE') { 56794 this.movieGeometry = new BoxGeometry(256, 256, 256); 56795 this.movieMaterial = new MeshBasicMaterial({ 56796 map: this.videoTexture, 56797 overdraw: true, 56798 side: BackSide 56799 }); 56800 var left = [new Vector2(0, 0.5), new Vector2(0.333, 0.5), new Vector2(0.333, 1), new Vector2(0, 1)]; 56801 var right = [new Vector2(0.333, 0.5), new Vector2(0.666, 0.5), new Vector2(0.666, 1), new Vector2(0.333, 1)]; 56802 var top = [new Vector2(0.666, 0.5), new Vector2(1, 0.5), new Vector2(1, 1), new Vector2(0.666, 1)]; 56803 var bottom = [new Vector2(0, 0), new Vector2(0.333, 0), new Vector2(0.333, 0.5), new Vector2(0, 0.5)]; 56804 var front = [new Vector2(0.333, 0), new Vector2(0.666, 0), new Vector2(0.666, 0.5), new Vector2(0.333, 0.5)]; 56805 var back = [new Vector2(0.666, 0), new Vector2(1, 0), new Vector2(1, 0.5), new Vector2(0.666, 0.5)]; 56806 this.movieGeometry.faceVertexUvs[0] = []; 56807 this.movieGeometry.faceVertexUvs[0][0] = [right[2], right[1], right[3]]; 56808 this.movieGeometry.faceVertexUvs[0][1] = [right[1], right[0], right[3]]; 56809 this.movieGeometry.faceVertexUvs[0][2] = [left[2], left[1], left[3]]; 56810 this.movieGeometry.faceVertexUvs[0][3] = [left[1], left[0], left[3]]; 56811 this.movieGeometry.faceVertexUvs[0][4] = [top[2], top[1], top[3]]; 56812 this.movieGeometry.faceVertexUvs[0][5] = [top[1], top[0], top[3]]; 56813 this.movieGeometry.faceVertexUvs[0][6] = [bottom[2], bottom[1], bottom[3]]; 56814 this.movieGeometry.faceVertexUvs[0][7] = [bottom[1], bottom[0], bottom[3]]; 56815 this.movieGeometry.faceVertexUvs[0][8] = [front[2], front[1], front[3]]; 56816 this.movieGeometry.faceVertexUvs[0][9] = [front[1], front[0], front[3]]; 56817 this.movieGeometry.faceVertexUvs[0][10] = [back[2], back[1], back[3]]; 56818 this.movieGeometry.faceVertexUvs[0][11] = [back[1], back[0], back[3]]; 56819 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); 56820 this.movieScreen.position.set(position.x, position.y, position.z); 56821 this.movieScreen.rotation.y = -Math.PI; 56822 this.scene.add(this.movieScreen); 56823 } else if (projection === '180' || projection === '180_LR' || projection === '180_MONO') { 56824 var _geometry = new SphereGeometry(256, this.options_.sphereDetail, this.options_.sphereDetail, Math.PI, Math.PI); // Left eye view 56825 56826 56827 _geometry.scale(-1, 1, 1); 56828 56829 var _uvs = _geometry.faceVertexUvs[0]; 56830 56831 if (projection !== '180_MONO') { 56832 for (var _i2 = 0; _i2 < _uvs.length; _i2++) { 56833 for (var _j2 = 0; _j2 < 3; _j2++) { 56834 _uvs[_i2][_j2].x *= 0.5; 56835 } 56836 } 56837 } 56838 56839 this.movieGeometry = new BufferGeometry().fromGeometry(_geometry); 56840 this.movieMaterial = new MeshBasicMaterial({ 56841 map: this.videoTexture, 56842 overdraw: true 56843 }); 56844 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); // display in left eye only 56845 56846 this.movieScreen.layers.set(1); 56847 this.scene.add(this.movieScreen); // Right eye view 56848 56849 _geometry = new SphereGeometry(256, this.options_.sphereDetail, this.options_.sphereDetail, Math.PI, Math.PI); 56850 56851 _geometry.scale(-1, 1, 1); 56852 56853 _uvs = _geometry.faceVertexUvs[0]; 56854 56855 for (var _i3 = 0; _i3 < _uvs.length; _i3++) { 56856 for (var _j3 = 0; _j3 < 3; _j3++) { 56857 _uvs[_i3][_j3].x *= 0.5; 56858 _uvs[_i3][_j3].x += 0.5; 56859 } 56860 } 56861 56862 this.movieGeometry = new BufferGeometry().fromGeometry(_geometry); 56863 this.movieMaterial = new MeshBasicMaterial({ 56864 map: this.videoTexture, 56865 overdraw: true 56866 }); 56867 this.movieScreen = new Mesh(this.movieGeometry, this.movieMaterial); // display in right eye only 56868 56869 this.movieScreen.layers.set(2); 56870 this.scene.add(this.movieScreen); 56871 } else if (projection === 'EAC' || projection === 'EAC_LR') { 56872 var makeScreen = function makeScreen(mapMatrix, scaleMatrix) { 56873 // "Continuity correction?": because of discontinuous faces and aliasing, 56874 // we truncate the 2-pixel-wide strips on all discontinuous edges, 56875 var contCorrect = 2; 56876 _this2.movieGeometry = new BoxGeometry(256, 256, 256); 56877 _this2.movieMaterial = new ShaderMaterial({ 56878 overdraw: true, 56879 side: BackSide, 56880 uniforms: { 56881 mapped: { 56882 value: _this2.videoTexture 56883 }, 56884 mapMatrix: { 56885 value: mapMatrix 56886 }, 56887 contCorrect: { 56888 value: contCorrect 56889 }, 56890 faceWH: { 56891 value: new Vector2(1 / 3, 1 / 2).applyMatrix3(scaleMatrix) 56892 }, 56893 vidWH: { 56894 value: new Vector2(_this2.videoTexture.image.videoWidth, _this2.videoTexture.image.videoHeight).applyMatrix3(scaleMatrix) 56895 } 56896 }, 56897 vertexShader: "\nvarying vec2 vUv;\nuniform mat3 mapMatrix;\n\nvoid main() {\n vUv = (mapMatrix * vec3(uv, 1.)).xy;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);\n}", 56898 fragmentShader: "\nvarying vec2 vUv;\nuniform sampler2D mapped;\nuniform vec2 faceWH;\nuniform vec2 vidWH;\nuniform float contCorrect;\n\nconst float PI = 3.1415926535897932384626433832795;\n\nvoid main() {\n vec2 corner = vUv - mod(vUv, faceWH) + vec2(0, c
56898ontCorrect / vidWH.y);\n\n vec2 faceWHadj = faceWH - vec2(0, contCorrect * 2. / vidWH.y);\n\n vec2 p = (vUv - corner) / faceWHadj - .5;\n vec2 q = 2. / PI * atan(2. * p) + .5;\n\n vec2 eUv = corner + q * faceWHadj;\n\n gl_FragColor = texture2D(mapped, eUv);\n}" 56899 }); 56900 var right = [new Vector2(0, 1 / 2), new Vector2(1 / 3, 1 / 2), new Vector2(1 / 3, 1), new Vector2(0, 1)]; 56901 var front = [new Vector2(1 / 3, 1 / 2), new Vector2(2 / 3, 1 / 2), new Vector2(2 / 3, 1), new Vector2(1 / 3, 1)]; 56902 var left = [new Vector2(2 / 3, 1 / 2), new Vector2(1, 1 / 2), new Vector2(1, 1), new Vector2(2 / 3, 1)]; 56903 var bottom = [new Vector2(1 / 3, 0), new Vector2(1 / 3, 1 / 2), new Vector2(0, 1 / 2), new Vector2(0, 0)]; 56904 var back = [new Vector2(1 / 3, 1 / 2), new Vector2(1 / 3, 0), new Vector2(2 / 3, 0), new Vector2(2 / 3, 1 / 2)]; 56905 var top = [new Vector2(1, 0), new Vector2(1, 1 / 2), new Vector2(2 / 3, 1 / 2), new Vector2(2 / 3, 0)]; 56906 56907 for (var _i4 = 0, _arr = [right, front, left, bottom, back, top]; _i4 < _arr.length; _i4++) { 56908 var face = _arr[_i4]; 56909 var height = _this2.videoTexture.image.videoHeight; 56910 var lowY = 1; 56911 var highY = 0; 56912 56913 for (var _iterator = face, _isArray = Array.isArray(_iterator), _i5 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { 56914 var _ref; 56915 56916 if (_isArray) { 56917 if (_i5 >= _iterator.length) break; 56918 _ref = _iterator[_i5++]; 56919 } else { 56920 _i5 = _iterator.next(); 56921 if (_i5.done) break; 56922 _ref = _i5.value; 56923 } 56924 56925 var vector = _ref; 56926 56927 if (vector.y < lowY) { 56928 lowY = vector.y; 56929 } 56930 56931 if (vector.y > highY) { 56932 highY = vector.y; 56933 } 56934 } 56935 56936 for (var _iterator2 = face, _isArray2 = Array.isArray(_iterator2), _i6 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { 56937 var _ref2; 56938 56939 if (_isArray2) { 56940 if (_i6 >= _iterator2.length) break; 56941 _ref2 = _iterator2[_i6++]; 56942 } else { 56943 _i6 = _iterator2.next(); 56944 if (_i6.done) break; 56945 _ref2 = _i6.value; 56946 } 56947 56948 var _vector = _ref2; 56949 56950 if (Math.abs(_vector.y - lowY) < Number.EPSILON) { 56951 _vector.y += contCorrect / height; 56952 } 56953 56954 if (Math.abs(_vector.y - highY) < Number.EPSILON) { 56955 _vector.y -= contCorrect / height; 56956 } 56957 56958 _vector.x = _vector.x / height * (height - contCorrect * 2) + contCorrect / height; 56959 } 56960 } 56961 56962 _this2.movieGeometry.faceVertexUvs[0] = []; 56963 _this2.movieGeometry.faceVertexUvs[0][0] = [right[2], right[1], right[3]]; 56964 _this2.movieGeometry.faceVertexUvs[0][1] = [right[1], right[0], right[3]]; 56965 _this2.movieGeometry.faceVertexUvs[0][2] = [left[2], left[1], left[3]]; 56966 _this2.movieGeometry.faceVertexUvs[0][3] = [left[1], left[0], left[3]]; 56967 _this2.movieGeometry.faceVertexUvs[0][4] = [top[2], top[1], top[3]]; 56968 _this2.movieGeometry.faceVertexUvs[0][5] = [top[1], top[0], top[3]]; 56969 _this2.movieGeometry.faceVertexUvs[0][6] = [bottom[2], bottom[1], bottom[3]]; 56970 _this2.movieGeometry.faceVertexUvs[0][7] = [bottom[1], bottom[0], bottom[3]]; 56971 _this2.movieGeometry.faceVertexUvs[0][8] = [front[2], front[1], front[3]]; 56972 _this2.movieGeometry.faceVertexUvs[0][9] = [front[1], front[0], front[3]]; 56973 _this2.movieGeometry.faceVertexUvs[0][10] = [back[2], back[1], back[3]]; 56974 _this2.movieGeometry.faceVertexUvs[0][11] = [back[1], back[0], back[3]]; 56975 _this2.movieScreen = new Mesh(_this2.movieGeometry, _this2.movieMaterial); 56976 56977 _this2.movieScreen.position.set(position.x, position.y, position.z); 56978 56979 _this2.movieScreen.rotation.y = -Math.PI; 56980 return _this2.movieScreen; 56981 }; 56982 56983 if (projection === 'EAC') { 56984 this.scene.add(makeScreen(new Matrix3(), new Matrix3())); 56985 } else { 56986 var scaleMatrix = new Matrix3().set(0, 0.5, 0, 1, 0, 0, 0, 0, 1); 56987 makeScreen(new Matrix3().set(0, -0.5, 0.5, 1, 0, 0, 0, 0, 1), scaleMatrix); // display in left eye only 56988 56989 this.movieScreen.layers.set(1); 56990 this.scene.add(this.movieScreen); 56991 makeScreen(new Matrix3().set(0, -0.5, 1, 1, 0, 0, 0, 0, 1), scaleMatrix); // display in right eye only 56992 56993 this.movieScreen.layers.set(2); 56994 this.scene.add(this.movieScreen); 56995 } 56996 } 56997 56998 this.currentProjection_ = projection; 56999 }; 57000 57001 _proto.triggerError_ = function triggerError_(errorObj) { 57002 // if we have videojs-errors use it 57003 if (this.videojsErrorsSupport_) { 57004 this.player_.error(errorObj); // if we don't have videojs-errors just use a normal player error 57005 } else { 57006 // strip any html content from the error message 57007 // as it is not supported outside of videojs-errors 57008 var div = document$1.createElement('div'); 57009 div.innerHTML = errors[errorObj.code].message; 57010 var message = div.textContent || div.innerText || ''; 57011 this.player_.error({ 57012 code: errorObj.code, 57013 message: message 57014 }); 57015 } 57016 }; 57017 57018 _proto.log = function log() { 57019 if (!this.options_.debug) { 57020 return; 57021 } 57022 57023 for (var _len = arguments.length, msgs = new Array(_len), _key = 0; _key < _len; _key++) { 57024 msgs[_key] = arguments[_key]; 57025 } 57026
57027 msgs.forEach(function (msg) { 57028 videojs.log('VR: ', msg); 57029 }); 57030 }; 57031 57032 _proto.handleVrDisplayActivate_ = function handleVrDisplayActivate_() { 57033 var _this3 = this; 57034 57035 if (!this.vrDisplay) { 57036 return; 57037 } 57038 57039 this.vrDisplay.requestPresent([{ 57040 source: this.renderedCanvas 57041 }]).then(function () { 57042 if (!_this3.vrDisplay.cardboardUI_ || !videojs.browser.IS_IOS) { 57043 return; 57044 } // webvr-polyfill/cardboard ui only watches for click events 57045 // to tell that the back arrow button is pressed during cardboard vr. 57046 // but somewhere along the line these events are silenced with preventDefault 57047 // but only on iOS, so we translate them ourselves here 57048 57049 57050 var touches = []; 57051 57052 var iosCardboardTouchStart_ = function iosCardboardTouchStart_(e) { 57053 for (var i = 0; i < e.touches.length; i++) { 57054 touches.push(e.touches[i]); 57055 } 57056 }; 57057 57058 var iosCardboardTouchEnd_ = function iosCardboardTouchEnd_(e) { 57059 if (!touches.length) { 57060 return; 57061 } 57062 57063 touches.forEach(function (t) { 57064 var simulatedClick = new window$1.MouseEvent('click', { 57065 screenX: t.screenX, 57066 screenY: t.screenY, 57067 clientX: t.clientX, 57068 clientY: t.clientY 57069 }); 57070 57071 _this3.renderedCanvas.dispatchEvent(simulatedClick); 57072 }); 57073 touches = []; 57074 }; 57075 57076 _this3.renderedCanvas.addEventListener('touchstart', iosCardboardTouchStart_); 57077 57078 _this3.renderedCanvas.addEventListener('touchend', iosCardboardTouchEnd_); 57079 57080 _this3.iosRevertTouchToClick_ = function () { 57081 _this3.renderedCanvas.removeEventListener('touchstart', iosCardboardTouchStart_); 57082 57083 _this3.renderedCanvas.removeEventListener('touchend', iosCardboardTouchEnd_); 57084 57085 _this3.iosRevertTouchToClick_ = null; 57086 }; 57087 }); 57088 }; 57089 57090 _proto.handleVrDisplayDeactivate_ = function handleVrDisplayDeactivate_() { 57091 if (!this.vrDisplay || !this.vrDisplay.isPresenting) { 57092 return; 57093 } 57094 57095 if (this.iosRevertTouchToClick_) { 57096 this.iosRevertTouchToClick_(); 57097 } 57098 57099 this.vrDisplay.exitPresent(); 57100 }; 57101 57102 _proto.requestAnimationFrame = function requestAnimationFrame(fn) { 57103 if (this.vrDisplay) { 57104 return this.vrDisplay.requestAnimationFrame(fn); 57105 } 57106 57107 return this.player_.requestAnimationFrame(fn); 57108 }; 57109 57110 _proto.cancelAnimationFrame = function cancelAnimationFrame(id) { 57111 if (this.vrDisplay) { 57112 return this.vrDisplay.cancelAnimationFrame(id); 57113 } 57114 57115 return this.player_.cancelAnimationFrame(id); 57116 }; 57117 57118 _proto.togglePlay_ = function togglePlay_() { 57119 if (this.player_.paused()) { 57120 this.player_.play(); 57121 } else { 57122 this.player_.pause(); 57123 } 57124 }; 57125 57126 _proto.animate_ = function animate_() { 57127 if (!this.initialized_) { 57128 return; 57129 } 57130 57131 if (this.getVideoEl_().readyState === this.getVideoEl_().HAVE_ENOUGH_DATA) { 57132 if (this.videoTexture) { 57133 this.videoTexture.needsUpdate = true; 57134 } 57135 } 57136 57137 this.controls3d.update(); 57138 57139 if (this.omniController) { 57140 this.omniController.update(this.camera); 57141 } 57142 57143 this.effect.render(this.scene, this.camera); 57144 57145 if (window$1.navigator.getGamepads) { 57146 // Grab all gamepads 57147 var gamepads = window$1.navigator.getGamepads(); 57148 57149 for (var i = 0; i < gamepads.length; ++i) { 57150 var gamepad = gamepads[i]; // Make sure gamepad is defined 57151 // Only take input if state has changed since we checked last 57152 57153 if (!gamepad || !gamepad.timestamp || gamepad.timestamp === this.prevTimestamps_[i]) { 57154 continue; 57155 } 57156 57157 for (var j = 0; j < gamepad.buttons.length; ++j) { 57158 if (gamepad.buttons[j].pressed) { 57159 this.togglePlay_(); 57160 this.prevTimestamps_[i] = gamepad.timestamp; 57161 break; 57162 } 57163 } 57164 } 57165 } 57166 57167 this.camera.getWorldDirection(this.cameraVector); 57168 this.animationFrameId_ = this.requestAnimationFrame(this.animate_); 57169 }; 57170 57171 _proto.handleResize_ = function handleResize_() { 57172 var width = this.player_.currentWidth(); 57173 var height = this.player_.currentHeight(); 57174 this.effect.setSize(width, height, false); 57175 this.camera.aspect = width / height; 57176 this.camera.updateProjectionMatrix(); 57177 }; 57178 57179 _proto.setProjection = function setProjection(projection) { 57180 if (!getInternalProjectionName(projection)) { 57181 videojs.log.error('videojs-vr: please pass a valid projection ' + validProjections.join(', ')); 57182 return; 57183 } 57184 57185 this.currentProjection_ = projection; 57186 this.defaultProjection_ = projection; 57187 }; 57188
57189 _proto.init = function init() { 57190 var _this4 = this; 57191 57192 this.reset(); 57193 this.camera = new PerspectiveCamera(75, this.player_.currentWidth() / this.player_.currentHeight(), 1, 1000); // Store vector representing the direction in which the camera is looking, in world space. 57194 57195 this.cameraVector = new Vector3(); 57196 57197 if (this.currentProjection_ === '360_LR' || this.currentProjection_ === '360_TB' || this.currentProjection_ === '180' || this.currentProjection_ === '180_LR' || this.currentProjection_ === '180_MONO' || this.currentProjection_ === 'EAC_LR') { 57198 // Render left eye when not in VR mode 57199 this.camera.layers.enable(1); 57200 } 57201 57202 this.scene = new Scene(); 57203 this.videoTexture = new VideoTexture(this.getVideoEl_()); // shared regardless of wether VideoTexture is used or 57204 // an image canvas is used 57205 57206 this.videoTexture.generateMipmaps = false; 57207 this.videoTexture.minFilter = LinearFilter; 57208 this.videoTexture.magFilter = LinearFilter; 57209 this.videoTexture.format = RGBFormat; 57210 this.changeProjection_(this.currentProjection_); 57211 57212 if (this.currentProjection_ === 'NONE') { 57213 this.log('Projection is NONE, dont init'); 57214 this.reset(); 57215 return; 57216 } 57217 57218 this.player_.removeChild('BigPlayButton'); 57219 this.player_.addChild('BigVrPlayButton', {}, this.bigPlayButtonIndex_); 57220 this.player_.bigPlayButton = this.player_.getChild('BigVrPlayButton'); // mobile devices, or cardboard forced to on 57221 57222 if (this.options_.forceCardboard || videojs.browser.IS_ANDROID || videojs.browser.IS_IOS) { 57223 this.addCardboardButton_(); 57224 } // if ios remove full screen toggle 57225 57226 57227 if (videojs.browser.IS_IOS && this.player_.controlBar && this.player_.controlBar.fullscreenToggle) { 57228 this.player_.controlBar.fullscreenToggle.hide(); 57229 } 57230 57231 this.camera.position.set(0, 0, 0); 57232 this.renderer = new WebGLRenderer({ 57233 devicePixelRatio: window$1.devicePixelRatio, 57234 alpha: false, 57235 clearColor: 0xffffff, 57236 antialias: true 57237 }); 57238 var webglContext = this.renderer.getContext('webgl'); 57239 var oldTexImage2D = webglContext.texImage2D; 57240 /* this is a workaround since threejs uses try catch */ 57241 57242 webglContext.texImage2D = function () { 57243 try { 57244 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 57245 args[_key2] = arguments[_key2]; 57246 } 57247 57248 return oldTexImage2D.apply(webglContext, args); 57249 } catch (e) { 57250 _this4.reset(); 57251 57252 _this4.player_.pause(); 57253 57254 _this4.triggerError_({ 57255 code: 'web-vr-hls-cors-not-supported', 57256 dismiss: false 57257 }); 57258 57259 throw new Error(e); 57260 } 57261 }; 57262 57263 this.renderer.setSize(this.player_.currentWidth(), this.player_.currentHeight(), false); 57264 this.effect = new VREffect(this.renderer); 57265 this.effect.setSize(this.player_.currentWidth(), this.player_.currentHeight(), false); 57266 this.vrDisplay = null; // Previous timestamps for gamepad updates 57267 57268 this.prevTimestamps_ = []; 57269 this.renderedCanvas = this.renderer.domElement; 57270 this.renderedCanvas.setAttribute('style', 'width: 100%; height: 100%; position: absolute; top:0;'); 57271 var videoElStyle = this.getVideoEl_().style; 57272 this.player_.el().insertBefore(this.renderedCanvas, this.player_.el().firstChild); 57273 videoElStyle.zIndex = '-1'; 57274 videoElStyle.opacity = '0'; 57275 57276 if (window$1.navigator.getVRDisplays) { 57277 this.log('is supported, getting vr displays'); 57278 window$1.navigator.getVRDisplays().then(function (displays) { 57279 if (displays.length > 0) { 57280 _this4.log('Displays found', displays); 57281 57282 _this4.vrDisplay = displays[0]; // Native WebVR Head Mounted Displays (HMDs) like the HTC Vive 57283 // also need the cardboard button to enter fully immersive mode 57284 // so, we want to add the button if we're not polyfilled. 57285 57286 if (!_this4.vrDisplay.isPolyfilled) { 57287 _this4.log('Real HMD found using VRControls', _this4.vrDisplay); 57288 57289 _this4.addCardboardButton_(); // We use VRControls here since we are working with an HMD 57290 // and we only want orientation controls. 57291 57292 57293 _this4.controls3d = new VRControls(_this4.camera); 57294 } 57295 } 57296 57297 if (!_this4.controls3d) { 57298 _this4.log('no HMD found Using Orbit & Orientation Controls'); 57299 57300 var options = { 57301 camera: _this4.camera, 57302 canvas: _this4.renderedCanvas, 57303 // check if its a half sphere view projection 57304 halfView: _this4.currentProjection_.indexOf('180') === 0, 57305 orientation: videojs.browser.IS_IOS || videojs.browser.IS_ANDROID || false 57306 }; 57307 57308 if (_this4.options_.motionControls === false) { 57309 options.orientation = false;
57310 } 57311 57312 _this4.controls3d = new OrbitOrientationControls(options); 57313 _this4.canvasPlayerControls = new CanvasPlayerControls(_this4.player_, _this4.renderedCanvas); 57314 } 57315 57316 _this4.animationFrameId_ = _this4.requestAnimationFrame(_this4.animate_); 57317 }); 57318 } else if (window$1.navigator.getVRDevices) { 57319 this.triggerError_({ 57320 code: 'web-vr-out-of-date', 57321 dismiss: false 57322 }); 57323 } else { 57324 this.triggerError_({ 57325 code: 'web-vr-not-supported', 57326 dismiss: false 57327 }); 57328 } 57329 57330 if (this.options_.omnitone) { 57331 var audiocontext = AudioContext.getContext(); 57332 this.omniController = new OmnitoneController(audiocontext, this.options_.omnitone, this.getVideoEl_(), this.options_.omnitoneOptions); 57333 this.omniController.one('audiocontext-suspended', function () { 57334 _this4.player.pause(); 57335 57336 _this4.player.one('playing', function () { 57337 audiocontext.resume(); 57338 }); 57339 }); 57340 } 57341 57342 this.on(this.player_, 'fullscreenchange', this.handleResize_); 57343 window$1.addEventListener('vrdisplaypresentchange', this.handleResize_, true); 57344 window$1.addEventListener('resize', this.handleResize_, true); 57345 window$1.addEventListener('vrdisplayactivate', this.handleVrDisplayActivate_, true); 57346 window$1.addEventListener('vrdisplaydeactivate', this.handleVrDisplayDeactivate_, true); 57347 this.initialized_ = true; 57348 this.trigger('initialized'); 57349 }; 57350 57351 _proto.addCardboardButton_ = function addCardboardButton_() { 57352 if (!this.player_.controlBar.getChild('CardboardButton')) { 57353 this.player_.controlBar.addChild('CardboardButton', {}); 57354 } 57355 }; 57356 57357 _proto.getVideoEl_ = function getVideoEl_() { 57358 return this.player_.el().getElementsByTagName('video')[0]; 57359 }; 57360 57361 _proto.reset = function reset() { 57362 if (!this.initialized_) { 57363 return; 57364 } 57365 57366 if (this.omniController) { 57367 this.omniController.off('audiocontext-suspended'); 57368 this.omniController.dispose(); 57369 this.omniController = undefined; 57370 } 57371 57372 if (this.controls3d) { 57373 this.controls3d.dispose(); 57374 this.controls3d = null; 57375 } 57376 57377 if (this.canvasPlayerControls) { 57378 this.canvasPlayerControls.dispose(); 57379 this.canvasPlayerControls = null; 57380 } 57381 57382 if (this.effect) { 57383 this.effect.dispose(); 57384 this.effect = null; 57385 } 57386 57387 window$1.removeEventListener('resize', this.handleResize_, true); 57388 window$1.removeEventListener('vrdisplaypresentchange', this.handleResize_, true); 57389 window$1.removeEventListener('vrdisplayactivate', this.handleVrDisplayActivate_, true); 57390 window$1.removeEventListener('vrdisplaydeactivate', this.handleVrDisplayDeactivate_, true); // re-add the big play button to player 57391 57392 if (!this.player_.getChild('BigPlayButton')) { 57393 this.player_.addChild('BigPlayButton', {}, this.bigPlayButtonIndex_); 57394 } 57395 57396 if (this.player_.getChild('BigVrPlayButton')) { 57397 this.player_.removeChild('BigVrPlayButton'); 57398 } // remove the cardboard button 57399 57400 57401 if (this.player_.getChild('CardboardButton')) { 57402 this.player_.controlBar.removeChild('CardboardButton'); 57403 } // show the fullscreen again 57404 57405 57406 if (videojs.browser.IS_IOS && this.player_.controlBar && this.player_.controlBar.fullscreenToggle) { 57407 this.player_.controlBar.fullscreenToggle.show(); 57408 } // reset the video element style so that it will be displayed 57409 57410 57411 var videoElStyle = this.getVideoEl_().style; 57412 videoElStyle.zIndex = ''; 57413 videoElStyle.opacity = ''; // set the current projection to the default 57414 57415 this.currentProjection_ = this.defaultProjection_; // reset the ios touch to click workaround 57416 57417 if (this.iosRevertTouchToClick_) { 57418 this.iosRevertTouchToClick_(); 57419 } // remove the old canvas 57420 57421 57422 if (this.renderedCanvas) { 57423 this.renderedCanvas.parentNode.removeChild(this.renderedCanvas); 57424 } 57425 57426 if (this.animationFrameId_) { 57427 this.cancelAnimationFrame(this.animationFrameId_); 57428 } 57429 57430 this.initialized_ = false; 57431 }; 57432 57433 _proto.dispose = function dispose() { 57434 _Plugin.prototype.dispose.call(this); 57435 57436 this.reset(); 57437 }; 57438 57439 _proto.polyfillVersion = function polyfillVersion() { 57440 return WebVRPolyfill.version; 57441 }; 57442 57443 return VR; 57444 }(Plugin); 57445 57446 VR.prototype.setTimeout = Component.prototype.setTimeout; 57447 VR.prototype.clearTimeout = Component.prototype.clearTimeout; 57448 VR.VERSION = version; 57449 videojs.registerPlugin('vr', VR); 57450 57451 return VR; 57452 57453 }))); 57454// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/admin/lib/pannellum/src/js/videojs-pannellum-plugin.js?ver=1 57455/* 57456 * Video.js plugin for Pannellum 57457 * Copyright (c) 2015-2018 Matthew Petroff 57458 * MIT License 57459 */ 57460 57461(function(document, videojs, pannellum) { 57462'use strict'; 57463 57464var registerPlugin = videojs.registerPlugin || videojs.plugin; // Use registerPlugin for Video.js >= 6 57465registerPlugin('pannellum', function(config) { 57466 // Create Pannellum instance 57467 var player = this;
vendor: 1,462 bytes, lines 57468-57510
57468 var container = player.el(); 57469 var vid = container.getElementsByTagName('video')[0], 57470 pnlmContainer = document.createElement('div'); 57471 pnlmContainer.style.zIndex = '0'; 57472 config = config || {}; 57473 config.type = 'equirectangular'; 57474 config.dynamic = true; 57475 config.showZoomCtrl = false; 57476 config.showFullscreenCtrl = false; 57477 config.autoLoad = true; 57478 config.panorama = vid; 57479 pnlmContainer.style.visibility = 'hidden'; 57480 player.pnlmViewer = pannellum.viewer(pnlmContainer, config); 57481 container.insertBefore(pnlmContainer, container.firstChild); 57482 vid.style.display = 'none'; 57483 57484 // Handle update settings 57485 player.on('play', function() { 57486 if (vid.readyState > 1) 57487 player.pnlmViewer.setUpdate(true); 57488 }); 57489 player.on('canplay', function() { 57490 if (!player.paused()) 57491 player.pnlmViewer.setUpdate(true); 57492 }); 57493 player.on('pause', function() { 57494 player.pnlmViewer.setUpdate(false); 57495 }); 57496 player.on('loadeddata', function() { 57497 pnlmContainer.style.visibility = 'visible'; 57498 }); 57499 player.on('seeking', function() { 57500 if (player.paused()) 57501 player.pnlmViewer.setUpdate(true); 57502 }); 57503 player.on('seeked', function() { 57504 if (player.paused()) 57505 player.pnlmViewer.setUpdate(false); 57506 }); 57507}); 57508 57509})(document, videojs, pannellum); 57510// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/admin/js/owl.carousel.js?ver=6.8.2
vendor: 39,702 bytes, lines 57511-59026
57511/** 57512 * Owl carousel 57513 * @version 2.3.4 57514 * @author Bartosz Wojciechowski 57515 * @author David Deutsch 57516 * @license The MIT License (MIT) 57517 * @todo Lazy Load Icon 57518 * @todo prevent animationend bubling 57519 * @todo itemsScaleUp 57520 * @todo Test Zepto 57521 * @todo stagePadding calculate wrong active classes 57522 */ 57523;(function($, window, document, undefined) { 57524 57525 /** 57526 * Creates a carousel. 57527 * @class The Owl Carousel. 57528 * @public 57529 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 57530 * @param {Object} [options] - The options 57531 */ 57532 function Owl(element, options) { 57533 57534 /** 57535 * Current settings for the carousel. 57536 * @public 57537 */ 57538 this.settings = null; 57539 57540 /** 57541 * Current options set by the caller including defaults. 57542 * @public 57543 */ 57544 this.options = $.extend({}, Owl.Defaults, options); 57545 57546 /** 57547 * Plugin element. 57548 * @public 57549 */ 57550 this.$element = $(element); 57551 57552 /** 57553 * Proxied event handlers. 57554 * @protected 57555 */ 57556 this._handlers = {}; 57557 57558 /** 57559 * References to the running plugins of this carousel. 57560 * @protected 57561 */ 57562 this._plugins = {}; 57563 57564 /** 57565 * Currently suppressed events to prevent them from being retriggered. 57566 * @protected 57567 */ 57568 this._supress = {}; 57569 57570 /** 57571 * Absolute current position. 57572 * @protected 57573 */ 57574 this._current = null; 57575 57576 /** 57577 * Animation speed in milliseconds. 57578 * @protected 57579 */ 57580 this._speed = null; 57581 57582 /** 57583 * Coordinates of all items in pixel. 57584 * @todo The name of this member is missleading. 57585 * @protected 57586 */ 57587 this._coordinates = []; 57588 57589 /** 57590 * Current breakpoint. 57591 * @todo Real media queries would be nice. 57592 * @protected 57593 */ 57594 this._breakpoint = null; 57595 57596 /** 57597 * Current width of the plugin element. 57598 */ 57599 this._width = null; 57600 57601 /** 57602 * All real items. 57603 * @protected 57604 */ 57605 this._items = []; 57606 57607 /** 57608 * All cloned items. 57609 * @protected 57610 */ 57611 this._clones = []; 57612 57613 /** 57614 * Merge values of all items. 57615 * @todo Maybe this could be part of a plugin. 57616 * @protected 57617 */ 57618 this._mergers = []; 57619 57620 /** 57621 * Widths of all items. 57622 */ 57623 this._widths = []; 57624 57625 /** 57626 * Invalidated parts within the update process. 57627 * @protected 57628 */ 57629 this._invalidated = {}; 57630 57631 /** 57632 * Ordered list of workers for the update process. 57633 * @protected 57634 */ 57635 this._pipe = []; 57636 57637 /** 57638 * Current state information for the drag operation. 57639 * @todo #261 57640 * @protected 57641 */ 57642 this._drag = { 57643 time: null, 57644 target: null, 57645 pointer: null, 57646 stage: { 57647 start: null, 57648 current: null 57649 }, 57650 direction: null 57651 }; 57652 57653 /** 57654 * Current state information and their tags. 57655 * @type {Object} 57656 * @protected 57657 */ 57658 this._states = { 57659 current: {}, 57660 tags: { 57661 'initializing': [ 'busy' ], 57662 'animating': [ 'busy' ], 57663 'dragging': [ 'interacting' ] 57664 } 57665 }; 57666 57667 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 57668 this._handlers[handler] = $.proxy(this[handler], this); 57669 }, this)); 57670 57671 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 57672 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 57673 = new plugin(this); 57674 }, this)); 57675 57676 $.each(Owl.Workers, $.proxy(function(priority, worker) { 57677 this._pipe.push({ 57678 'filter': worker.filter, 57679 'run': $.proxy(worker.run, this) 57680 }); 57681 }, this)); 57682 57683 this.setup(); 57684 this.initialize(); 57685 } 57686 57687 /** 57688 * Default options for the carousel. 57689 * @public 57690 */ 57691 Owl.Defaults = { 57692 items: 3, 57693 loop: false, 57694 center: false, 57695 rewind: false, 57696 checkVisibility: true, 57697 57698 mouseDrag: true, 57699 touchDrag: true, 57700 pullDrag: true, 57701 freeDrag: false, 57702 57703 margin: 0, 57704 stagePadding: 0, 57705 57706 merge: false, 57707 mergeFit: true, 57708 autoWidth: false, 57709 57710 startPosition: 0, 57711 rtl: false, 57712 57713 smartSpeed: 250, 57714 fluidSpeed: false, 57715 dragEndSpeed: false, 57716 57717 responsive: {}, 57718 responsiveRefreshRate: 200, 57719 responsiveBaseElement: window, 57720 57721 fallbackEasing: 'swing', 57722 slideTransition: '', 57723 57724 info: false, 57725 57726 nestedItemSelector: false, 57727 itemElement: 'div', 57728 stageElement: 'div', 57729 57730 refreshClass: 'owl-refresh', 57731 loadedClass: 'owl-loaded', 57732 loadingClass: 'owl-loading', 57733 rtlClass: 'owl-rtl', 57734 responsiveClass: 'owl-responsive', 57735 dragClass: 'owl-drag', 57736 itemClass: 'owl-item', 57737 stageClass: 'owl-stage', 57738 stageOuterClass: 'owl-stage-outer', 57739 grabClass: 'owl-grab' 57740 }; 57741 57742 /** 57743 * Enumeration for width. 57744 * @public 57745 * @readonly 57746 * @enum {String} 57747 */ 57748 Owl.Width = { 57749 Default: 'default', 57750 Inner: 'inner', 57751 Outer: 'outer' 57752 }; 57753 57754 /** 57755 * Enumeration for types. 57756 * @public 57757 * @readonly 57758 * @enum {String} 57759 */ 57760 Owl.Type = { 57761 Event: 'event', 57762 State: 'state' 57763 }; 57764 57765 /** 57766 * Contains all registered plugins. 57767 * @public 57768 */ 57769 Owl.Plugins = {}; 57770 57771 /** 57772 * List of workers involved in the update process. 57773 */ 57774 Owl.Workers = [ { 57775 filter: [ 'width', 'settings' ], 57776 run: function() { 57777 this._width = this.$element.width(); 57778 } 57779 }, { 57780 filter: [ 'width', 'items', 'settings' ], 57781 run: function(cache) { 57782 cache.current = this._items && this._items[this.relative(this._current)]; 57783 } 57784 }, { 57785 filter: [ 'items', 'settings' ], 57786 run: function() { 57787 this.$stage.children('.cloned').remove(); 57788 } 57789 }, { 57790 filter: [ 'width', 'items', 'settings' ], 57791 run: function(cache) { 57792 var margin = this.settings.margin || '', 57793 grid = !this.settings.autoWidth, 57794 rtl = this.settings.rtl, 57795 css = { 57796 'width': 'auto', 57797 'margin-left': rtl ? margin : '', 57798 'margin-right': rtl ? '' : margin 57799 }; 57800 57801 !grid && this.$stage.children().css(css); 57802 57803 cache.css = css; 57804 } 57805 }, { 57806 filter: [ 'width', 'items', 'settings' ], 57807 run: function(cache) { 57808 var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin, 57809 merge = null, 57810 iterator = this._items.length, 57811 grid = !this.settings.autoWidth, 57812 widths = []; 57813 57814 cache.items = { 57815 merge: false, 57816 width: width 57817 }; 57818 57819 while (iterator--) { 57820 merge = this._mergers[iterator]; 57821 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 57822 57823 cache.items.merge = merge > 1 || cache.items.merge; 57824 57825 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 57826 } 57827 57828 this._widths = widths; 57829 } 57830 }, { 57831 filter: [ 'items', 'settings' ], 57832 run: function() { 57833 var clones = [], 57834 items = this._items, 57835 settings = this.settings, 57836 // TODO: Should be computed from number of min width items in stage 57837 view = Math.max(settings.items * 2, 4), 57838 size = Math.ceil(items.length / 2) * 2, 57839 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 57840 append = '', 57841 prepend = ''; 57842 57843 repeat /= 2; 57844 57845 while (repeat > 0) { 57846 // Switch to only using appended clones 57847 clones.push(this.normalize(clones.length / 2, true)); 57848 $(items[clones[clones.length - 1]][0]).clone(true).addClass('cloned').appendTo(this.$stage); 57849 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 57850 $(items[clones[clones.length - 1]][0]).clone(true).addClass('cloned').prependTo(this.$stage); 57851 repeat -= 1; 57852 } 57853 this._clones = clones; 57854 } 57855 }, { 57856 filter: [ 'width', 'items', 'settings' ], 57857 run: function() { 57858 var rtl = this.settings.rtl ? 1 : -1, 57859 size = this._clones.length + this._items.length, 57860 iterator = -1, 57861 previous = 0, 57862 current = 0, 57863 coordinates = []; 57864 57865 while (++iterator < size) { 57866 previous = coordinates[iterator - 1] || 0; 57867 current = this._widths[this.relative(iterator)] + this.settings.margin; 57868 coordinates.push(previous + current * rtl); 57869 } 57870 57871 this._coordinates = coordinates; 57872 } 57873 }, { 57874 filter: [ 'width', 'items', 'settings' ], 57875 run: function() { 57876 var padding = this.settings.stagePadding, 57877 coordinates = this._coordinates, 57878 css = { 57879 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 57880 'padding-left': padding || '', 57881 'padding-right': padding || '' 57882 }; 57883 57884 this.$stage.css(css); 57885 } 57886 }, { 57887 filter: [ 'width', 'items', 'settings' ], 57888 run: function(cache) { 57889 var iterator = this._coordinates.length, 57890 grid = !this.settings.autoWidth, 57891 items = this.$stage.children(); 57892 57893 if (grid && cache.items.merge) { 57894 while (iterator--) { 57895 cache.css.width = this._widths[this.relative(iterator)]; 57896 items.eq(iterator).css(cache.css); 57897 } 57898 } else if (grid) { 57899 cache.css.width = cache.items.width; 57900 items.css(cache.css); 57901 } 57902 } 57903 }, { 57904 filter: [ 'items' ], 57905 run: function() { 57906 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 57907 } 57908 }, { 57909 filter: [ 'width', 'items', 'settings' ], 57910 run: function(cache) { 57911 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 57912 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 57913 this.reset(cache.current); 57914 } 57915 }, { 57916 filter: [ 'position' ], 57917 run: function() { 57918 this.animate(this.coordinates(this._current)); 57919 } 57920 }, { 57921 filter: [ 'width', 'position', 'items', 'settings' ], 57922 run: function() { 57923 var rtl = this.settings.rtl ? 1 : -1, 57924 padding = this.settings.stagePadding * 2, 57925 begin = this.coordinates(this.current()) + padding, 57926 end = begin + this.width() * rtl, 57927 inner, outer, matches = [], i, n; 57928 57929 for (i = 0, n = this._coordinates.length; i < n; i++) { 57930 inner = this._coordinates[i - 1] || 0; 57931 outer = Math.abs(this._coordinates[i]) + padding * rtl; 57932 57933 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 57934 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 57935 matches.push(i); 57936 } 57937 } 57938 57939 this.$stage.children('.active').removeClass('active'); 57940 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 57941 57942 this.$stage.children('.center').removeClass('center'); 57943 if (this.settings.center) { 57944 this.$stage.children().eq(this.current()).addClass('center'); 57945 } 57946 } 57947 } ]; 57948 57949 /** 57950 * Create the stage DOM element 57951 */ 57952 Owl.prototype.initializeStage = function() { 57953 this.$stage = this.$element.find('.' + this.settings.stageClass); 57954 57955 // if the stage is already in the DOM, grab it and skip stage initialization 57956 if (this.$stage.length) { 57957 return; 57958 } 57959 57960 this.$element.addClass(this.options.loadingClass); 57961 57962 // create stage 57963 this.$stage = $('<' + this.settings.stageElement + '>', { 57964 "class": this.settings.stageClass 57965 }).wrap( $( '<div/>', { 57966 "class": this.settings.stageOuterClass 57967 })); 57968 57969 // append stage 57970 this.$element.append(this.$stage.parent()); 57971 }; 57972 57973 /** 57974 * Create item DOM elements 57975 */ 57976 Owl.prototype.initializeItems = function() { 57977 var $items = this.$element.find('.owl-item'); 57978 57979 // if the items are already in the DOM, grab them and skip item initialization 57980 if ($items.length) { 57981 this._items = $items.get().map(function(item) { 57982 return $(item); 57983 }); 57984 57985 this._mergers = this._items.map(function() { 57986 return 1; 57987 }); 57988 57989 this.refresh(); 57990 57991 return; 57992 } 57993 57994 // append content 57995 this.replace(this.$element.children().not(this.$stage.parent())); 57996 57997 // check visibility 57998 if (this.isVisible()) { 57999 // update view 58000 this.refresh(); 58001 } else { 58002 // invalidate width 58003 this.invalidate('width'); 58004 } 58005 58006 this.$element 58007 .removeClass(this.options.loadingClass) 58008 .addClass(this.options.loadedClass); 58009 }; 58010 58011 /** 58012 * Initializes the carousel. 58013 * @protected 58014 */ 58015 Owl.prototype.initialize = function() { 58016 this.enter('initializing'); 58017 this.trigger('initialize'); 58018 58019 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 58020 58021 if (this.settings.autoWidth && !this.is('pre-loading')) { 58022 var imgs, nestedSelector, width; 58023 imgs = this.$element.find('img'); 58024 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 58025 width = this.$element.children(nestedSelector).width(); 58026 58027 if (imgs.length && width <= 0) { 58028 this.preloadAutoWidthImages(imgs); 58029 } 58030 } 58031 58032 this.initializeStage(); 58033 this.initializeItems(); 58034 58035 // register event handlers 58036 this.registerEventHandlers(); 58037 58038 this.leave('initializing'); 58039 this.trigger('initialized'); 58040 }; 58041 58042 /** 58043 * @returns {Boolean} visibility of $element 58044 * if you know the carousel will always be visible you can set `checkVisibility` to `false` to 58045 * prevent the expensive browser layout forced reflow the $element.is(':visible') does 58046 */ 58047 Owl.prototype.isVisible = function() { 58048 return this.settings.checkVisibility 58049 ? this.$element.is(':visible') 58050 : true; 58051 }; 58052 58053 /** 58054 * Setups the current settings. 58055 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 58056 * @todo Support for media queries by using `matchMedia` would be nice. 58057 * @public 58058 */ 58059 Owl.prototype.setup = function() { 58060 var viewport = this.viewport(), 58061 overwrites = this.options.responsive, 58062 match = -1, 58063 settings = null; 58064 58065 if (!overwrites) { 58066 settings = $.extend({}, this.options); 58067 } else { 58068 $.each(overwrites, function(breakpoint) { 58069 if (breakpoint <= viewport && breakpoint > match) { 58070 match = Number(breakpoint); 58071 } 58072 }); 58073 58074 settings = $.extend({}, this.options, overwrites[match]); 58075 if (typeof settings.stagePadding === 'function') { 58076 settings.stagePadding = settings.stagePadding(); 58077 } 58078 delete settings.responsive; 58079 58080 // responsive class 58081 if (settings.responsiveClass) { 58082 this.$element.attr('class', 58083 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 58084 ); 58085 } 58086 } 58087 58088 this.trigger('change', { property: { name: 'settings', value: settings } }); 58089 this._breakpoint = match; 58090 this.settings = settings; 58091 this.invalidate('settings'); 58092 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 58093 }; 58094 58095 /** 58096 * Updates option logic if necessery. 58097 * @protected 58098 */ 58099 Owl.prototype.optionsLogic = function() { 58100 if (this.settings.autoWidth) { 58101 this.settings.stagePadding = false; 58102 this.settings.merge = false; 58103 } 58104 }; 58105 58106 /** 58107 * Prepares an item before add. 58108 * @todo Rename event parameter `content` to `item`. 58109 * @protected 58110 * @returns {jQuery|HTMLElement} - The item container. 58111 */ 58112 Owl.prototype.prepare = function(item) { 58113 var event = this.trigger('prepare', { content: item }); 58114 58115 if (!event.data) { 58116 event.data = $('<' + this.settings.itemElement + '/>') 58117 .addClass(this.options.itemClass).append(item) 58118 } 58119 58120 this.trigger('prepared', { content: event.data }); 58121 58122 return event.data; 58123 }; 58124 58125 /** 58126 * Updates the view. 58127 * @public 58128 */ 58129 Owl.prototype.update = function() { 58130 var i = 0, 58131 n = this._pipe.length, 58132 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 58133 cache = {}; 58134 58135 while (i < n) { 58136 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 58137 this._pipe[i].run(cache); 58138 } 58139 i++; 58140 } 58141 58142 this._invalidated = {}; 58143 58144 !this.is('valid') && this.enter('valid'); 58145 }; 58146 58147 /** 58148 * Gets the width of the view. 58149 * @public 58150 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 58151 * @returns {Number} - The width of the view in pixel. 58152 */ 58153 Owl.prototype.width = function(dimension) { 58154 dimension = dimension || Owl.Width.Default; 58155 switch (dimension) { 58156 case Owl.Width.Inner: 58157 case Owl.Width.Outer: 58158 return this._width; 58159 default: 58160 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 58161 } 58162 }; 58163 58164 /** 58165 * Refreshes the carousel primarily for adaptive purposes. 58166 * @public 58167 */ 58168 Owl.prototype.refresh = function(resizing) { 58169 resizing = resizing || false; 58170 58171 this.enter('refreshing'); 58172 this.trigger('refresh'); 58173 58174 this.setup(); 58175 58176 this.optionsLogic(); 58177 58178 this.$element.addClass(this.options.refreshClass); 58179 58180 this.update(); 58181 58182 if (!resizing) { 58183 this.onResize(); 58184 } 58185 58186 this.$element.removeClass(this.options.refreshClass); 58187 58188 this.leave('refreshing'); 58189 this.trigger('refreshed'); 58190 }; 58191 58192 /** 58193 * Checks window `resize` event. 58194 * @protected 58195 */ 58196 Owl.prototype.onThrottledResize = function() { 58197 window.clearTimeout(this.resizeTimer); 58198 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 58199 }; 58200 58201 /** 58202 * Checks window `resize` event. 58203 * @protected 58204 */ 58205 Owl.prototype.onResize = function() { 58206 var resizing = true; 58207 58208 if (!this._items.length) { 58209 return false; 58210 } 58211 58212 if (this._width === this.$element.width()) { 58213 return false; 58214 } 58215 58216 if (!this.isVisible()) { 58217 return false; 58218 } 58219 58220 this.enter('resizing'); 58221 58222 if (this.trigger('resize').isDefaultPrevented()) { 58223 this.leave('resizing'); 58224 return false; 58225 } 58226 58227 this.invalidate('width'); 58228 58229 this.refresh(resizing); 58230 58231 this.leave('resizing'); 58232 this.trigger('resized'); 58233 }; 58234 58235 /** 58236 * Registers event handlers. 58237 * @todo Check `msPointerEnabled` 58238 * @todo #261 58239 * @protected 58240 */ 58241 Owl.prototype.registerEventHandlers = function() { 58242 if ($.support.transition) { 58243 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 58244 } 58245 58246 if (this.settings.responsive !== false) { 58247 this.on(window, 'resize', this._handlers.onThrottledResize); 58248 } 58249 58250 if (this.settings.mouseDrag) { 58251 this.$element.addClass(this.options.dragClass); 58252 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 58253 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 58254 } 58255 58256 if (this.settings.touchDrag){ 58257 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 58258 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 58259 } 58260 }; 58261 58262 /** 58263 * Handles `touchstart` and `mousedown` events. 58264 * @todo Horizontal swipe threshold as option 58265 * @todo #261 58266 * @protected 58267 * @param {Event} event - The event arguments. 58268 */ 58269 Owl.prototype.onDragStart = function(event) { 58270 var stage = null; 58271 58272 if (event.which === 3) { 58273 return; 58274 } 58275 58276 if ($.support.transform) { 58277 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 58278 stage = { 58279 x: stage[stage.length === 16 ? 12 : 4], 58280 y: stage[stage.length === 16 ? 13 : 5] 58281 }; 58282 } else { 58283 stage = this.$stage.position(); 58284 stage = { 58285 x: this.settings.rtl ? 58286 stage.left + this.$stage.width() - this.width() + this.settings.margin : 58287 stage.left, 58288 y: stage.top 58289 }; 58290 } 58291 58292 if (this.is('animating')) { 58293 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 58294 this.invalidate('position'); 58295 } 58296 58297 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 58298 58299 this.speed(0); 58300 58301 this._drag.time = new Date().getTime(); 58302 this._drag.target = $(event.target); 58303 this._drag.stage.start = stage; 58304 this._drag.stage.current = stage; 58305 this._drag.pointer = this.pointer(event); 58306 58307 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 58308 58309 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 58310 var delta = this.difference(this._drag.pointer, this.pointer(event)); 58311 58312 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 58313 58314 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 58315 return; 58316 } 58317 58318 event.preventDefault(); 58319 58320 this.enter('dragging'); 58321 this.trigger('drag'); 58322 }, this)); 58323 }; 58324 58325 /** 58326 * Handles the `touchmove` and `mousemove` events. 58327 * @todo #261 58328 * @protected 58329 * @param {Event} event - The event arguments. 58330 */ 58331 Owl.prototype.onDragMove = function(event) { 58332 var minimum = null, 58333 maximum = null, 58334 pull = null, 58335 delta = this.difference(this._drag.pointer, this.pointer(event)), 58336 stage = this.difference(this._drag.stage.start, delta); 58337 58338 if (!this.is('dragging')) { 58339 return; 58340 } 58341 58342 event.preventDefault(); 58343 58344 if (this.settings.loop) { 58345 minimum = this.coordinates(this.minimum()); 58346 maximum = this.coordinates(this.maximum() + 1) - minimum; 58347 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 58348 } else { 58349 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 58350 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 58351 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 58352 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 58353 } 58354 58355 this._drag.stage.current = stage; 58356 58357 this.animate(stage.x); 58358 }; 58359 58360 /** 58361 * Handles the `touchend` and `mouseup` events. 58362 * @todo #261 58363 * @todo Threshold for click event 58364 * @protected 58365 * @param {Event} event - The event arguments. 58366 */ 58367 Owl.prototype.onDragEnd = function(event) { 58368 var delta = this.difference(this._drag.pointer, this.pointer(event)), 58369 stage = this._drag.stage.current, 58370 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 58371 58372 $(document).off('.owl.core'); 58373 58374 this.$element.removeClass(this.options.grabClass); 58375 58376 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 58377 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 58378 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 58379 this.invalidate('position'); 58380 this.update(); 58381 58382 this._drag.direction = direction; 58383 58384 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 58385 this._drag.target.one('click.owl.core', function() { return false; }); 58386 } 58387 } 58388 58389 if (!this.is('dragging')) { 58390 return; 58391 } 58392 58393 this.leave('dragging'); 58394 this.trigger('dragged'); 58395 }; 58396 58397 /** 58398 * Gets absolute position of the closest item for a coordinate. 58399 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 58400 * @protected 58401 * @param {Number} coordinate - The coordinate in pixel. 58402 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 58403 * @return {Number} - The absolute position of the closest item. 58404 */ 58405 Owl.prototype.closest = function(coordinate, direction) { 58406 var position = -1, 58407 pull = 30, 58408 width = this.width(), // visible carousel width 58409 count = this.settings.items, 58410 itemWidth = Math.round(width / count), 58411 coordinates = this.coordinates(); 58412 58413 if (!this.settings.freeDrag) { 58414 // check closest item 58415 $.each(coordinates, $.proxy(function(index, value) { 58416 // on a left pull, check on current index 58417 if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) { 58418 position = index; 58419 // on a right pull, check on previous index 58420 // to do so, subtract width from value and set position = index + 1 58421 } else if (direction === 'right' && coordinate > value - itemWidth - pull && coordinate < value - itemWidth + pull) { 58422 position = index + 1; 58423 } else if (this.op(coordinate, '<', value) 58424 && this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) { 58425 position = direction === 'left' ? index + 1 : index; 58426 } 58427 return position === -1; 58428 }, this)); 58429 } 58430 58431 if (!this.settings.loop) { 58432 // non loop boundries 58433 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 58434 position = coordinate = this.minimum(); 58435 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 58436 position = coordinate = this.maximum(); 58437 } 58438 } 58439 58440 return position; 58441 }; 58442 58443 /** 58444 * Animates the stage. 58445 * @todo #270 58446 * @public 58447 * @param {Number} coordinate - The coordinate in pixels. 58448 */ 58449 Owl.prototype.animate = function(coordinate) { 58450 var animate = this.speed() > 0; 58451 58452 this.is('animating') && this.onTransitionEnd(); 58453 58454 if (animate) { 58455 this.enter('animating'); 58456 this.trigger('translate'); 58457 } 58458 58459 if ($.support.transform3d && $.support.transition) { 58460 this.$stage.css({ 58461 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 58462 transition: (this.speed() / 1000) + 's' + ( 58463 this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' 58464 ) 58465 }); 58466 } else if (animate) { 58467 this.$stage.animate({ 58468 left: coordinate + 'px' 58469 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 58470 } else { 58471 this.$stage.css({ 58472 left: coordinate + 'px' 58473 }); 58474 } 58475 }; 58476 58477 /** 58478 * Checks whether the carousel is in a specific state or not. 58479 * @param {String} state - The state to check. 58480 * @returns {Boolean} - The flag which indicates if the carousel is busy. 58481 */ 58482 Owl.prototype.is = function(state) { 58483 return this._states.current[state] && this._states.current[state] > 0; 58484 }; 58485 58486 /** 58487 * Sets the absolute position of the current item. 58488 * @public 58489 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 58490 * @returns {Number} - The absolute position of the current item. 58491 */ 58492 Owl.prototype.current = function(position) { 58493 if (position === undefined) { 58494 return this._current; 58495 } 58496 58497 if (this._items.length === 0) { 58498 return undefined; 58499 } 58500 58501 position = this.normalize(position); 58502 58503 if (this._current !== position) { 58504 var event = this.trigger('change', { property: { name: 'position', value: position } }); 58505 58506 if (event.data !== undefined) { 58507 position = this.normalize(event.data); 58508 } 58509 58510 this._current = position; 58511 58512 this.invalidate('position'); 58513 58514 this.trigger('changed', { property: { name: 'position', value: this._current } }); 58515 } 58516 58517 return this._current; 58518 }; 58519 58520 /** 58521 * Invalidates the given part of the update routine. 58522 * @param {String} [part] - The part to invalidate. 58523 * @returns {Array.<String>} - The invalidated parts. 58524 */ 58525 Owl.prototype.invalidate = function(part) { 58526 if ($.type(part) === 'string') { 58527 this._invalidated[part] = true; 58528 this.is('valid') && this.leave('valid'); 58529 } 58530 return $.map(this._invalidated, function(v, i) { return i }); 58531 }; 58532 58533 /** 58534 * Resets the absolute position of the current item. 58535 * @public 58536 * @param {Number} position - The absolute position of the new item. 58537 */ 58538 Owl.prototype.reset = function(position) { 58539 position = this.normalize(position); 58540 58541 if (position === undefined) { 58542 return; 58543 } 58544 58545 this._speed = 0; 58546 this._current = position; 58547 58548 this.suppress([ 'translate', 'translated' ]); 58549 58550 this.animate(this.coordinates(position)); 58551 58552 this.release([ 'translate', 'translated' ]); 58553 }; 58554 58555 /** 58556 * Normalizes an absolute or a relative position of an item. 58557 * @public 58558 * @param {Number} position - The absolute or relative position to normalize. 58559 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 58560 * @returns {Number} - The normalized position. 58561 */ 58562 Owl.prototype.normalize = function(position, relative) { 58563 var n = this._items.length, 58564 m = relative ? 0 : this._clones.length; 58565 58566 if (!this.isNumeric(position) || n < 1) { 58567 position = undefined; 58568 } else if (position < 0 || position >= n + m) { 58569 position = ((position - m / 2) % n + n) % n + m / 2; 58570 } 58571 58572 return position; 58573 }; 58574 58575 /** 58576 * Converts an absolute position of an item into a relative one. 58577 * @public 58578 * @param {Number} position - The absolute position to convert. 58579 * @returns {Number} - The converted position. 58580 */ 58581 Owl.prototype.relative = function(position) { 58582 position -= this._clones.length / 2; 58583 return this.normalize(position, true); 58584 }; 58585 58586 /** 58587 * Gets the maximum position for the current item. 58588 * @public 58589 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 58590 * @returns {Number} 58591 */ 58592 Owl.prototype.maximum = function(relative) { 58593 var settings = this.settings, 58594 maximum = this._coordinates.length, 58595 iterator, 58596 reciprocalItemsWidth, 58597 elementWidth; 58598 58599 if (settings.loop) { 58600 maximum = this._clones.length / 2 + this._items.length - 1; 58601 } else if (settings.autoWidth || settings.merge) { 58602 iterator = this._items.length; 58603 if (iterator) { 58604 reciprocalItemsWidth = this._items[--iterator].width(); 58605 elementWidth = this.$element.width(); 58606 while (iterator--) { 58607 reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin; 58608 if (reciprocalItemsWidth > elementWidth) { 58609 break; 58610 } 58611 } 58612 } 58613 maximum = iterator + 1; 58614 } else if (settings.center) { 58615 maximum = this._items.length - 1; 58616 } else { 58617 maximum = this._items.length - settings.items; 58618 } 58619 58620 if (relative) { 58621 maximum -= this._clones.length / 2; 58622 } 58623 58624 return Math.max(maximum, 0); 58625 }; 58626 58627 /** 58628 * Gets the minimum position for the current item. 58629 * @public 58630 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 58631 * @returns {Number} 58632 */ 58633 Owl.prototype.minimum = function(relative) { 58634 return relative ? 0 : this._clones.length / 2; 58635 }; 58636 58637 /** 58638 * Gets an item at the specified relative position. 58639 * @public 58640 * @param {Number} [position] - The relative position of the item. 58641 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 58642 */ 58643 Owl.prototype.items = function(position) { 58644 if (position === undefined) { 58645 return this._items.slice(); 58646 } 58647 58648 position = this.normalize(position, true); 58649 return this._items[position]; 58650 }; 58651 58652 /** 58653 * Gets an item at the specified relative position. 58654 * @public 58655 * @param {Number} [position] - The relative position of the item. 58656 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 58657 */ 58658 Owl.prototype.mergers = function(position) { 58659 if (position === undefined) { 58660 return this._mergers.slice(); 58661 } 58662 58663 position = this.normalize(position, true); 58664 return this._mergers[position]; 58665 }; 58666 58667 /** 58668 * Gets the absolute positions of clones for an item. 58669 * @public 58670 * @param {Number} [position] - The relative position of the item. 58671 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 58672 */ 58673 Owl.prototype.clones = function(position) { 58674 var odd = this._clones.length / 2, 58675 even = odd + this._items.length, 58676 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 58677 58678 if (position === undefined) { 58679 return $.map(this._clones, function(v, i) { return map(i) }); 58680 } 58681 58682 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 58683 }; 58684 58685 /** 58686 * Sets the current animation speed. 58687 * @public 58688 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 58689 * @returns {Number} - The current animation speed in milliseconds. 58690 */ 58691 Owl.prototype.speed = function(speed) { 58692 if (speed !== undefined) { 58693 this._speed = speed; 58694 } 58695 58696 return this._speed; 58697 }; 58698 58699 /** 58700 * Gets the coordinate of an item. 58701 * @todo The name of this method is missleanding. 58702 * @public 58703 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 58704 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 58705 */ 58706 Owl.prototype.coordinates = function(position) { 58707 var multiplier = 1, 58708 newPosition = position - 1, 58709 coordinate; 58710 58711 if (position === undefined) { 58712 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 58713 return this.coordinates(index); 58714 }, this)); 58715 } 58716 58717 if (this.settings.center) { 58718 if (this.settings.rtl) { 58719 multiplier = -1; 58720 newPosition = position + 1; 58721 } 58722 58723 coordinate = this._coordinates[position]; 58724 coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier; 58725 } else { 58726 coordinate = this._coordinates[newPosition] || 0; 58727 } 58728 58729 coordinate = Math.ceil(coordinate); 58730 58731 return coordinate; 58732 }; 58733 58734 /** 58735 * Calculates the speed for a translation. 58736 * @protected 58737 * @param {Number} from - The absolute position of the start item. 58738 * @param {Number} to - The absolute position of the target item. 58739 * @param {Number} [factor=undefined] - The time factor in milliseconds. 58740 * @returns {Number} - The time in milliseconds for the translation. 58741 */ 58742 Owl.prototype.duration = function(from, to, factor) { 58743 if (factor === 0) { 58744 return 0; 58745 } 58746 58747 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 58748 }; 58749 58750 /** 58751 * Slides to the specified item. 58752 * @public 58753 * @param {Number} position - The position of the item. 58754 * @param {Number} [speed] - The time in milliseconds for the transition. 58755 */ 58756 Owl.prototype.to = function(position, speed) { 58757 var current = this.current(), 58758 revert = null, 58759 distance = position - this.relative(current), 58760 direction = (distance > 0) - (distance < 0), 58761 items = this._items.length, 58762 minimum = this.minimum(), 58763 maximum = this.maximum(); 58764 58765 if (this.settings.loop) { 58766 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 58767 distance += direction * -1 * items; 58768 } 58769 58770 position = current + distance; 58771 revert = ((position - minimum) % items + items) % items + minimum; 58772 58773 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 58774 current = revert - distance; 58775 position = revert; 58776 this.reset(current); 58777 } 58778 } else if (this.settings.rewind) { 58779 maximum += 1; 58780 position = (position % maximum + maximum) % maximum; 58781 } else { 58782 position = Math.max(minimum, Math.min(maximum, position)); 58783 } 58784 58785 this.speed(this.duration(current, position, speed)); 58786 this.current(position); 58787 58788 if (this.isVisible()) { 58789 this.update(); 58790 } 58791 }; 58792 58793 /** 58794 * Slides to the next item. 58795 * @public 58796 * @param {Number} [speed] - The time in milliseconds for the transition. 58797 */ 58798 Owl.prototype.next = function(speed) { 58799 speed = speed || false; 58800 this.to(this.relative(this.current()) + 1, speed); 58801 }; 58802 58803 /** 58804 * Slides to the previous item. 58805 * @public 58806 * @param {Number} [speed] - The time in milliseconds for the transition. 58807 */ 58808 Owl.prototype.prev = function(speed) { 58809 speed = speed || false; 58810 this.to(this.relative(this.current()) - 1, speed); 58811 }; 58812 58813 /** 58814 * Handles the end of an animation. 58815 * @protected 58816 * @param {Event} event - The event arguments. 58817 */ 58818 Owl.prototype.onTransitionEnd = function(event) { 58819 58820 // if css2 animation then event object is undefined 58821 if (event !== undefined) { 58822 event.stopPropagation(); 58823 58824 // Catch only owl-stage transitionEnd event 58825 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 58826 return false; 58827 } 58828 } 58829 58830 this.leave('animating'); 58831 this.trigger('translated'); 58832 }; 58833 58834 /** 58835 * Gets viewport width. 58836 * @protected 58837 * @return {Number} - The width in pixel. 58838 */ 58839 Owl.prototype.viewport = function() { 58840 var width; 58841 if (this.options.responsiveBaseElement !== window) { 58842 width = $(this.options.responsiveBaseElement).width(); 58843 } else if (window.innerWidth) { 58844 width = window.innerWidth; 58845 } else if (document.documentElement && document.documentElement.clientWidth) { 58846 width = document.documentElement.clientWidth; 58847 } else { 58848 console.warn('Can not detect viewport width.'); 58849 } 58850 return width; 58851 }; 58852 58853 /** 58854 * Replaces the current content. 58855 * @public 58856 * @param {HTMLElement|jQuery|String} content - The new content. 58857 */ 58858 Owl.prototype.replace = function(content) { 58859 this.$stage.empty(); 58860 this._items = []; 58861 58862 if (content) { 58863 content = (content instanceof jQuery) ? content : $(content); 58864 } 58865 58866 if (this.settings.nestedItemSelector) { 58867 content = content.find('.' + this.settings.nestedItemSelector); 58868 } 58869 58870 content.filter(function() { 58871 return this.nodeType === 1; 58872 }).each($.proxy(function(index, item) { 58873 item = this.prepare(item); 58874 this.$stage.append(item); 58875 this._items.push(item); 58876 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 58877 }, this)); 58878 58879 this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 58880 58881 this.invalidate('items'); 58882 }; 58883 58884 /** 58885 * Adds an item. 58886 * @todo Use `item` instead of `content` for the event arguments. 58887 * @public 58888 * @param {HTMLElement|jQuery|String} content - The item content to add. 58889 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 58890 */ 58891 Owl.prototype.add = function(content, position) { 58892 var current = this.relative(this._current); 58893 58894 position = position === undefined ? this._items.length : this.normalize(position, true); 58895 content = content instanceof jQuery ? content : $(content); 58896 58897 this.trigger('add', { content: content, position: position }); 58898 58899 content = this.prepare(content); 58900 58901 if (this._items.length === 0 || position === this._items.length) { 58902 this._items.length === 0 && this.$stage.append(content); 58903 this._items.length !== 0 && this._items[position - 1].after(content); 58904 this._items.push(content); 58905 this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 58906 } else { 58907 this._items[position].before(content); 58908 this._items.splice(position, 0, content); 58909 this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 58910 } 58911 58912 this._items[current] && this.reset(this._items[current].index()); 58913 58914 this.invalidate('items'); 58915 58916 this.trigger('added', { content: content, position: position }); 58917 }; 58918 58919 /** 58920 * Removes an item by its position. 58921 * @todo Use `item` instead of `content` for the event arguments. 58922 * @public 58923 * @param {Number} position - The relative position of the item to remove. 58924 */ 58925 Owl.prototype.remove = function(position) { 58926 position = this.normalize(position, true); 58927 58928 if (position === undefined) { 58929 return; 58930 } 58931 58932 this.trigger('remove', { content: this._items[position], position: position }); 58933 58934 this._items[position].remove(); 58935 this._items.splice(position, 1); 58936 this._mergers.splice(position, 1); 58937 58938 this.invalidate('items'); 58939 58940 this.trigger('removed', { content: null, position: position }); 58941 }; 58942 58943 /** 58944 * Preloads images with auto width. 58945 * @todo Replace by a more generic approach 58946 * @protected 58947 */ 58948 Owl.prototype.preloadAutoWidthImages = function(images) { 58949 images.each($.proxy(function(i, element) { 58950 this.enter('pre-loading'); 58951 element = $(element); 58952 $(new Image()).one('load', $.proxy(function(e) { 58953 element.attr('src', e.target.src); 58954 element.css('opacity', 1); 58955 this.leave('pre-loading'); 58956 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 58957 }, this)).attr('src', (window.devicePixelRatio > 1) ? element.attr('data-src-retina') : element.attr('data-src') || element.attr('src')); 58958 }, this)); 58959 }; 58960 58961 /** 58962 * Destroys the carousel. 58963 * @public 58964 */ 58965 Owl.prototype.destroy = function() { 58966 58967 this.$element.off('.owl.core'); 58968 this.$stage.off('.owl.core'); 58969 $(document).off('.owl.core'); 58970 58971 if (this.settings.responsive !== false) { 58972 window.clearTimeout(this.resizeTimer); 58973 this.off(window, 'resize', this._handlers.onThrottledResize); 58974 } 58975 58976 for (var i in this._plugins) { 58977 this._plugins[i].destroy(); 58978 } 58979 58980 this.$stage.children('.cloned').remove(); 58981 58982 this.$stage.unwrap(); 58983 this.$stage.children().contents().unwrap(); 58984 this.$stage.children().unwrap(); 58985 this.$stage.remove(); 58986 this.$element 58987 .removeClass(this.options.refreshClass) 58988 .removeClass(this.options.loadingClass) 58989 .removeClass(this.options.loadedClass) 58990 .removeClass(this.options.rtlClass) 58991 .removeClass(this.options.dragClass) 58992 .removeClass(this.options.grabClass) 58993 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 58994 .removeData('owl.carousel'); 58995 }; 58996 58997 /** 58998 * Operators to calculate right-to-left and left-to-right. 58999 * @protected 59000 * @param {Number} [a] - The left side operand. 59001 * @param {String} [o] - The operator. 59002 * @param {Number} [b] - The right side operand. 59003 */ 59004 Owl.prototype.op = function(a, o, b) { 59005 var rtl = this.settings.rtl; 59006 switch (o) { 59007 case '<': 59008 return rtl ? a > b : a < b; 59009 case '>': 59010 return rtl ? a < b : a > b; 59011 case '>=': 59012 return rtl ? a <= b : a >= b; 59013 case '<=': 59014 return rtl ? a >= b : a <= b; 59015 default: 59016 break; 59017 } 59018 }; 59019 59020 /** 59021 * Attaches to an internal event. 59022 * @protected 59023 * @param {HTMLElement} element - The event source. 59024 * @param {String} event - The event name. 59025 * @param {Function} listener - The event handler to attach. 59026 * @param {Boolean} capture - Wether the event should be handled at the capturing p
vendor: 6,976 bytes, lines 59026-59266
59026hase or not. 59027 */ 59028 Owl.prototype.on = function(element, event, listener, capture) { 59029 if (element.addEventListener) { 59030 element.addEventListener(event, listener, capture); 59031 } else if (element.attachEvent) { 59032 element.attachEvent('on' + event, listener); 59033 } 59034 }; 59035 59036 /** 59037 * Detaches from an internal event. 59038 * @protected 59039 * @param {HTMLElement} element - The event source. 59040 * @param {String} event - The event name. 59041 * @param {Function} listener - The attached event handler to detach. 59042 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 59043 */ 59044 Owl.prototype.off = function(element, event, listener, capture) { 59045 if (element.removeEventListener) { 59046 element.removeEventListener(event, listener, capture); 59047 } else if (element.detachEvent) { 59048 element.detachEvent('on' + event, listener); 59049 } 59050 }; 59051 59052 /** 59053 * Triggers a public event. 59054 * @todo Remove `status`, `relatedTarget` should be used instead. 59055 * @protected 59056 * @param {String} name - The event name. 59057 * @param {*} [data=null] - The event data. 59058 * @param {String} [namespace=carousel] - The event namespace. 59059 * @param {String} [state] - The state which is associated with the event. 59060 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 59061 * @returns {Event} - The event arguments. 59062 */ 59063 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 59064 var status = { 59065 item: { count: this._items.length, index: this.current() } 59066 }, handler = $.camelCase( 59067 $.grep([ 'on', name, namespace ], function(v) { return v }) 59068 .join('-').toLowerCase() 59069 ), event = $.Event( 59070 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 59071 $.extend({ relatedTarget: this }, status, data) 59072 ); 59073 59074 if (!this._supress[name]) { 59075 $.each(this._plugins, function(name, plugin) { 59076 if (plugin.onTrigger) { 59077 plugin.onTrigger(event); 59078 } 59079 }); 59080 59081 this.register({ type: Owl.Type.Event, name: name }); 59082 this.$element.trigger(event); 59083 59084 if (this.settings && typeof this.settings[handler] === 'function') { 59085 this.settings[handler].call(this, event); 59086 } 59087 } 59088 59089 return event; 59090 }; 59091 59092 /** 59093 * Enters a state. 59094 * @param name - The state name. 59095 */ 59096 Owl.prototype.enter = function(name) { 59097 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 59098 if (this._states.current[name] === undefined) { 59099 this._states.current[name] = 0; 59100 } 59101 59102 this._states.current[name]++; 59103 }, this)); 59104 }; 59105 59106 /** 59107 * Leaves a state. 59108 * @param name - The state name. 59109 */ 59110 Owl.prototype.leave = function(name) { 59111 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 59112 this._states.current[name]--; 59113 }, this)); 59114 }; 59115 59116 /** 59117 * Registers an event or state. 59118 * @public 59119 * @param {Object} object - The event or state to register. 59120 */ 59121 Owl.prototype.register = function(object) { 59122 if (object.type === Owl.Type.Event) { 59123 if (!$.event.special[object.name]) { 59124 $.event.special[object.name] = {}; 59125 } 59126 59127 if (!$.event.special[object.name].owl) { 59128 var _default = $.event.special[object.name]._default; 59129 $.event.special[object.name]._default = function(e) { 59130 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 59131 return _default.apply(this, arguments); 59132 } 59133 return e.namespace && e.namespace.indexOf('owl') > -1; 59134 }; 59135 $.event.special[object.name].owl = true; 59136 } 59137 } else if (object.type === Owl.Type.State) { 59138 if (!this._states.tags[object.name]) { 59139 this._states.tags[object.name] = object.tags; 59140 } else { 59141 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 59142 } 59143 59144 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 59145 return $.inArray(tag, this._states.tags[object.name]) === i; 59146 }, this)); 59147 } 59148 }; 59149 59150 /** 59151 * Suppresses events. 59152 * @protected 59153 * @param {Array.<String>} events - The events to suppress. 59154 */ 59155 Owl.prototype.suppress = function(events) { 59156 $.each(events, $.proxy(function(index, event) { 59157 this._supress[event] = true; 59158 }, this)); 59159 }; 59160 59161 /** 59162 * Releases suppressed events. 59163 * @protected 59164 * @param {Array.<String>} events - The events to release. 59165 */ 59166 Owl.prototype.release = function(events) { 59167 $.each(events, $.proxy(function(index, event) { 59168 delete this._supress[event]; 59169 }, this)); 59170 }; 59171 59172 /** 59173 * Gets unified pointer coordinates from event. 59174 * @todo #261 59175 * @protected 59176 * @param {Event} - The `mousedown` or `touchstart` event. 59177 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 59178 */ 59179 Owl.prototype.pointer = function(event) { 59180 var result = { x: null, y: null }; 59181 59182 event = event.originalEvent || event || window.event; 59183 59184 event = event.touches && event.touches.length ? 59185 event.touches[0] : event.changedTouches && event.changedTouches.length ? 59186 event.changedTouches[0] : event; 59187 59188 if (event.pageX) { 59189 result.x = event.pageX; 59190 result.y = event.pageY; 59191 } else { 59192 result.x = event.clientX; 59193 result.y = event.clientY; 59194 } 59195 59196 return result; 59197 }; 59198 59199 /** 59200 * Determines if the input is a Number or something that can be coerced to a Number 59201 * @protected 59202 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested 59203 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number 59204 */ 59205 Owl.prototype.isNumeric = function(number) { 59206 return !isNaN(parseFloat(number)); 59207 }; 59208 59209 /** 59210 * Gets the difference of two vectors. 59211 * @todo #261 59212 * @protected 59213 * @param {Object} - The first vector. 59214 * @param {Object} - The second vector. 59215 * @returns {Object} - The difference. 59216 */ 59217 Owl.prototype.difference = function(first, second) { 59218 return { 59219 x: first.x - second.x, 59220 y: first.y - second.y 59221 }; 59222 }; 59223 59224 /** 59225 * The jQuery Plugin for the Owl Carousel 59226 * @todo Navigation plugin `next` and `prev` 59227 * @public 59228 */ 59229 $.fn.owlCarousel = function(option) { 59230 var args = Array.prototype.slice.call(arguments, 1); 59231 59232 return this.each(function() { 59233 var $this = $(this), 59234 data = $this.data('owl.carousel'); 59235 59236 if (!data) { 59237 data = new Owl(this, typeof option == 'object' && option); 59238 $this.data('owl.carousel', data); 59239 59240 $.each([ 59241 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 59242 ], function(i, event) { 59243 data.register({ type: Owl.Type.Event, name: event }); 59244 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 59245 if (e.namespace && e.relatedTarget !== this) { 59246 this.suppress([ event ]); 59247 data[event].apply(this, [].slice.call(arguments, 1)); 59248 this.release([ event ]); 59249 } 59250 }, data)); 59251 }); 59252 } 59253 59254 if (typeof option == 'string' && option.charAt(0) !== '_') { 59255 data[option].apply(data, args); 59256 } 59257 }); 59258 }; 59259 59260 /** 59261 * The constructor for the jQuery Plugin 59262 * @public 59263 */ 59264 $.fn.owlCarousel.Constructor = Owl; 59265 59266})(window.Zepto || window.jQuery, window, document);
vendor: 3,058 bytes, lines 59267-59376
59267// source --> https://vibeudlejning.dk/wp-content/plugins/wpvr-pro/admin/js/jquery.cookie.js?ver=1 59268/*! 59269 * jQuery Cookie Plugin v1.4.1 59270 * https://github.com/carhartl/jquery-cookie 59271 * 59272 * Copyright 2013 Klaus Hartl 59273 * Released under the MIT license 59274 */ 59275(function (factory) { 59276 if (typeof define === 'function' && define.amd) { 59277 // AMD 59278 define(['jquery'], factory); 59279 } else if (typeof exports === 'object') { 59280 // CommonJS 59281 factory(require('jquery')); 59282 } else { 59283 // Browser globals 59284 factory(jQuery); 59285 } 59286}(function ($) { 59287 59288 var pluses = /\+/g; 59289 59290 function encode(s) { 59291 return config.raw ? s : encodeURIComponent(s); 59292 } 59293 59294 function decode(s) { 59295 return config.raw ? s : decodeURIComponent(s); 59296 } 59297 59298 function stringifyCookieValue(value) { 59299 return encode(config.json ? JSON.stringify(value) : String(value)); 59300 } 59301 59302 function parseCookieValue(s) { 59303 if (s.indexOf('"') === 0) { 59304 // This is a quoted cookie as according to RFC2068, unescape... 59305 s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 59306 } 59307 59308 try { 59309 // Replace server-side written pluses with spaces. 59310 // If we can't decode the cookie, ignore it, it's unusable. 59311 // If we can't parse the cookie, ignore it, it's unusable. 59312 s = decodeURIComponent(s.replace(pluses, ' ')); 59313 return config.json ? JSON.parse(s) : s; 59314 } catch(e) {} 59315 } 59316 59317 function read(s, converter) { 59318 var value = config.raw ? s : parseCookieValue(s); 59319 return $.isFunction(converter) ? converter(value) : value; 59320 } 59321 59322 var config = $.cookie = function (key, value, options) { 59323 59324 // Write 59325 59326 if (value !== undefined && !$.isFunction(value)) { 59327 options = $.extend({}, config.defaults, options); 59328 59329 if (typeof options.expires === 'number') { 59330 var days = options.expires, t = options.expires = new Date(); 59331 t.setTime(+t + days * 864e+5); 59332 } 59333 59334 return (document.cookie = [ 59335 encode(key), '=', stringifyCookieValue(value), 59336 options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 59337 options.path ? '; path=' + options.path : '', 59338 options.domain ? '; domain=' + options.domain : '', 59339 options.secure ? '; secure' : '' 59340 ].join('')); 59341 } 59342 59343 // Read 59344 59345 var result = key ? undefined : {}; 59346 59347 // To prevent the for loop in the first place assign an empty array 59348 // in case there are no cookies at all. Also prevents odd result when 59349 // calling $.cookie(). 59350 var cookies = document.cookie ? document.cookie.split('; ') : []; 59351 59352 for (var i = 0, l = cookies.length; i < l; i++) { 59353 var parts = cookies[i].split('='); 59354 var name = decode(parts.shift()); 59355 var cookie = parts.join('='); 59356 59357 if (key && key === name) { 59358 // If second argument (value) is a function it's a converter... 59359 result = read(cookie, value); 59360 break; 59361 } 59362 59363 // Prevent storing a cookie that we couldn't decode. 59364 if (!key && (cookie = read(cookie)) !== undefined) { 59365 result[name] = cookie; 59366 } 59367 } 59368 59369 return result; 59370 }; 59371 59372 config.defaults = {}; 59373 59374 $.removeCookie = function (key, options) { 59375 if ($.cookie(key) === undefined) { 59376 return false;
59377 } 59378 59379 // Must not alter options, thus extending a fresh object... 59380 $.cookie(key, '', $.extend({}, options, { expires: -1 })); 59381 return !$.cookie(key); 59382 }; 59383 59384}));
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.