| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408 | 
							- import BoundingSphere from "../../Core/BoundingSphere.js";
 
- import Cartesian3 from "../../Core/Cartesian3.js";
 
- import Cartographic from "../../Core/Cartographic.js";
 
- import Clock from "../../Core/Clock.js";
 
- import defaultValue from "../../Core/defaultValue.js";
 
- import defer from "../../Core/defer.js";
 
- import defined from "../../Core/defined.js";
 
- import destroyObject from "../../Core/destroyObject.js";
 
- import DeveloperError from "../../Core/DeveloperError.js";
 
- import Event from "../../Core/Event.js";
 
- import EventHelper from "../../Core/EventHelper.js";
 
- import HeadingPitchRange from "../../Core/HeadingPitchRange.js";
 
- import Matrix4 from "../../Core/Matrix4.js";
 
- import ScreenSpaceEventType from "../../Core/ScreenSpaceEventType.js";
 
- import BoundingSphereState from "../../DataSources/BoundingSphereState.js";
 
- import ConstantPositionProperty from "../../DataSources/ConstantPositionProperty.js";
 
- import DataSourceCollection from "../../DataSources/DataSourceCollection.js";
 
- import DataSourceDisplay from "../../DataSources/DataSourceDisplay.js";
 
- import Entity from "../../DataSources/Entity.js";
 
- import EntityView from "../../DataSources/EntityView.js";
 
- import Property from "../../DataSources/Property.js";
 
- import Cesium3DTileset from "../../Scene/Cesium3DTileset.js";
 
- import computeFlyToLocationForRectangle from "../../Scene/computeFlyToLocationForRectangle.js";
 
- import ImageryLayer from "../../Scene/ImageryLayer.js";
 
- import SceneMode from "../../Scene/SceneMode.js";
 
- import TimeDynamicPointCloud from "../../Scene/TimeDynamicPointCloud.js";
 
- import knockout from "../../ThirdParty/knockout.js";
 
- import Animation from "../Animation/Animation.js";
 
- import AnimationViewModel from "../Animation/AnimationViewModel.js";
 
- import BaseLayerPicker from "../BaseLayerPicker/BaseLayerPicker.js";
 
- import createDefaultImageryProviderViewModels from "../BaseLayerPicker/createDefaultImageryProviderViewModels.js";
 
- import createDefaultTerrainProviderViewModels from "../BaseLayerPicker/createDefaultTerrainProviderViewModels.js";
 
- import CesiumWidget from "../CesiumWidget/CesiumWidget.js";
 
- import ClockViewModel from "../ClockViewModel.js";
 
- import FullscreenButton from "../FullscreenButton/FullscreenButton.js";
 
- import Geocoder from "../Geocoder/Geocoder.js";
 
- import getElement from "../getElement.js";
 
- import HomeButton from "../HomeButton/HomeButton.js";
 
- import InfoBox from "../InfoBox/InfoBox.js";
 
- import NavigationHelpButton from "../NavigationHelpButton/NavigationHelpButton.js";
 
- import ProjectionPicker from "../ProjectionPicker/ProjectionPicker.js";
 
- import SceneModePicker from "../SceneModePicker/SceneModePicker.js";
 
- import SelectionIndicator from "../SelectionIndicator/SelectionIndicator.js";
 
- import subscribeAndEvaluate from "../subscribeAndEvaluate.js";
 
- import Timeline from "../Timeline/Timeline.js";
 
- import VRButton from "../VRButton/VRButton.js";
 
- import Cesium3DTileFeature from "../../Scene/Cesium3DTileFeature.js";
 
- import JulianDate from "../../Core/JulianDate.js";
 
- import CesiumMath from "../../Core/Math.js";
 
- const boundingSphereScratch = new BoundingSphere();
 
- function onTimelineScrubfunction(e) {
 
-   const clock = e.clock;
 
-   clock.currentTime = e.timeJulian;
 
-   clock.shouldAnimate = false;
 
- }
 
- function getCesium3DTileFeatureDescription(feature) {
 
-   const propertyNames = feature.getPropertyNames();
 
-   let html = "";
 
-   propertyNames.forEach(function (propertyName) {
 
-     const value = feature.getProperty(propertyName);
 
-     if (defined(value)) {
 
-       html += `<tr><th>${propertyName}</th><td>${value}</td></tr>`;
 
-     }
 
-   });
 
-   if (html.length > 0) {
 
-     html = `<table class="cesium-infoBox-defaultTable"><tbody>${html}</tbody></table>`;
 
-   }
 
-   return html;
 
- }
 
- function getCesium3DTileFeatureName(feature) {
 
-   // We need to iterate all property names to find potential
 
-   // candidates, but since we prefer some property names
 
-   // over others, we store them in an indexed array
 
-   // and then use the first defined element in the array
 
-   // as the preferred choice.
 
-   let i;
 
-   const possibleNames = [];
 
-   const propertyNames = feature.getPropertyNames();
 
-   for (i = 0; i < propertyNames.length; i++) {
 
-     const propertyName = propertyNames[i];
 
-     if (/^name$/i.test(propertyName)) {
 
-       possibleNames[0] = feature.getProperty(propertyName);
 
-     } else if (/name/i.test(propertyName)) {
 
-       possibleNames[1] = feature.getProperty(propertyName);
 
-     } else if (/^title$/i.test(propertyName)) {
 
-       possibleNames[2] = feature.getProperty(propertyName);
 
-     } else if (/^(id|identifier)$/i.test(propertyName)) {
 
-       possibleNames[3] = feature.getProperty(propertyName);
 
-     } else if (/element/i.test(propertyName)) {
 
-       possibleNames[4] = feature.getProperty(propertyName);
 
-     } else if (/(id|identifier)$/i.test(propertyName)) {
 
-       possibleNames[5] = feature.getProperty(propertyName);
 
-     }
 
-   }
 
-   const length = possibleNames.length;
 
-   for (i = 0; i < length; i++) {
 
-     const item = possibleNames[i];
 
-     if (defined(item) && item !== "") {
 
-       return item;
 
-     }
 
-   }
 
-   return "Unnamed Feature";
 
- }
 
- function pickEntity(viewer, e) {
 
-   const picked = viewer.scene.pick(e.position);
 
-   if (defined(picked)) {
 
-     const id = defaultValue(picked.id, picked.primitive.id);
 
-     if (id instanceof Entity) {
 
-       return id;
 
-     }
 
-     if (picked instanceof Cesium3DTileFeature) {
 
-       return new Entity({
 
-         name: getCesium3DTileFeatureName(picked),
 
-         description: getCesium3DTileFeatureDescription(picked),
 
-         feature: picked,
 
-       });
 
-     }
 
-   }
 
-   // No regular entity picked.  Try picking features from imagery layers.
 
-   if (defined(viewer.scene.globe)) {
 
-     return pickImageryLayerFeature(viewer, e.position);
 
-   }
 
- }
 
- const scratchStopTime = new JulianDate();
 
- function trackDataSourceClock(timeline, clock, dataSource) {
 
-   if (defined(dataSource)) {
 
-     const dataSourceClock = dataSource.clock;
 
-     if (defined(dataSourceClock)) {
 
-       dataSourceClock.getValue(clock);
 
-       if (defined(timeline)) {
 
-         const startTime = dataSourceClock.startTime;
 
-         let stopTime = dataSourceClock.stopTime;
 
-         // When the start and stop times are equal, set the timeline to the shortest interval
 
-         // starting at the start time. This prevents an invalid timeline configuration.
 
-         if (JulianDate.equals(startTime, stopTime)) {
 
-           stopTime = JulianDate.addSeconds(
 
-             startTime,
 
-             CesiumMath.EPSILON2,
 
-             scratchStopTime
 
-           );
 
-         }
 
-         timeline.updateFromClock();
 
-         timeline.zoomTo(startTime, stopTime);
 
-       }
 
-     }
 
-   }
 
- }
 
- const cartesian3Scratch = new Cartesian3();
 
- function pickImageryLayerFeature(viewer, windowPosition) {
 
-   const scene = viewer.scene;
 
-   const pickRay = scene.camera.getPickRay(windowPosition);
 
-   const imageryLayerFeaturePromise = scene.imageryLayers.pickImageryLayerFeatures(
 
-     pickRay,
 
-     scene
 
-   );
 
-   if (!defined(imageryLayerFeaturePromise)) {
 
-     return;
 
-   }
 
-   // Imagery layer feature picking is asynchronous, so put up a message while loading.
 
-   const loadingMessage = new Entity({
 
-     id: "Loading...",
 
-     description: "Loading feature information...",
 
-   });
 
-   imageryLayerFeaturePromise.then(
 
-     function (features) {
 
-       // Has this async pick been superseded by a later one?
 
-       if (viewer.selectedEntity !== loadingMessage) {
 
-         return;
 
-       }
 
-       if (!defined(features) || features.length === 0) {
 
-         viewer.selectedEntity = createNoFeaturesEntity();
 
-         return;
 
-       }
 
-       // Select the first feature.
 
-       const feature = features[0];
 
-       const entity = new Entity({
 
-         id: feature.name,
 
-         description: feature.description,
 
-       });
 
-       if (defined(feature.position)) {
 
-         const ecfPosition = viewer.scene.globe.ellipsoid.cartographicToCartesian(
 
-           feature.position,
 
-           cartesian3Scratch
 
-         );
 
-         entity.position = new ConstantPositionProperty(ecfPosition);
 
-       }
 
-       viewer.selectedEntity = entity;
 
-     },
 
-     function () {
 
-       // Has this async pick been superseded by a later one?
 
-       if (viewer.selectedEntity !== loadingMessage) {
 
-         return;
 
-       }
 
-       viewer.selectedEntity = createNoFeaturesEntity();
 
-     }
 
-   );
 
-   return loadingMessage;
 
- }
 
- function createNoFeaturesEntity() {
 
-   return new Entity({
 
-     id: "None",
 
-     description: "No features found.",
 
-   });
 
- }
 
- function enableVRUI(viewer, enabled) {
 
-   const geocoder = viewer._geocoder;
 
-   const homeButton = viewer._homeButton;
 
-   const sceneModePicker = viewer._sceneModePicker;
 
-   const projectionPicker = viewer._projectionPicker;
 
-   const baseLayerPicker = viewer._baseLayerPicker;
 
-   const animation = viewer._animation;
 
-   const timeline = viewer._timeline;
 
-   const fullscreenButton = viewer._fullscreenButton;
 
-   const infoBox = viewer._infoBox;
 
-   const selectionIndicator = viewer._selectionIndicator;
 
-   const visibility = enabled ? "hidden" : "visible";
 
-   if (defined(geocoder)) {
 
-     geocoder.container.style.visibility = visibility;
 
-   }
 
-   if (defined(homeButton)) {
 
-     homeButton.container.style.visibility = visibility;
 
-   }
 
-   if (defined(sceneModePicker)) {
 
-     sceneModePicker.container.style.visibility = visibility;
 
-   }
 
-   if (defined(projectionPicker)) {
 
-     projectionPicker.container.style.visibility = visibility;
 
-   }
 
-   if (defined(baseLayerPicker)) {
 
-     baseLayerPicker.container.style.visibility = visibility;
 
-   }
 
-   if (defined(animation)) {
 
-     animation.container.style.visibility = visibility;
 
-   }
 
-   if (defined(timeline)) {
 
-     timeline.container.style.visibility = visibility;
 
-   }
 
-   if (
 
-     defined(fullscreenButton) &&
 
-     fullscreenButton.viewModel.isFullscreenEnabled
 
-   ) {
 
-     fullscreenButton.container.style.visibility = visibility;
 
-   }
 
-   if (defined(infoBox)) {
 
-     infoBox.container.style.visibility = visibility;
 
-   }
 
-   if (defined(selectionIndicator)) {
 
-     selectionIndicator.container.style.visibility = visibility;
 
-   }
 
-   if (viewer._container) {
 
-     const right =
 
-       enabled || !defined(fullscreenButton)
 
-         ? 0
 
-         : fullscreenButton.container.clientWidth;
 
-     viewer._vrButton.container.style.right = `${right}px`;
 
-     viewer.forceResize();
 
-   }
 
- }
 
- /**
 
-  * @typedef {Object} Viewer.ConstructorOptions
 
-  *
 
-  * Initialization options for the Viewer constructor
 
-  *
 
-  * @property {Boolean} [animation=true] If set to false, the Animation widget will not be created.
 
-  * @property {Boolean} [baseLayerPicker=true] If set to false, the BaseLayerPicker widget will not be created.
 
-  * @property {Boolean} [fullscreenButton=true] If set to false, the FullscreenButton widget will not be created.
 
-  * @property {Boolean} [vrButton=false] If set to true, the VRButton widget will be created.
 
-  * @property {Boolean|GeocoderService[]} [geocoder=true] If set to false, the Geocoder widget will not be created.
 
-  * @property {Boolean} [homeButton=true] If set to false, the HomeButton widget will not be created.
 
-  * @property {Boolean} [infoBox=true] If set to false, the InfoBox widget will not be created.
 
-  * @property {Boolean} [sceneModePicker=true] If set to false, the SceneModePicker widget will not be created.
 
-  * @property {Boolean} [selectionIndicator=true] If set to false, the SelectionIndicator widget will not be created.
 
-  * @property {Boolean} [timeline=true] If set to false, the Timeline widget will not be created.
 
-  * @property {Boolean} [navigationHelpButton=true] If set to false, the navigation help button will not be created.
 
-  * @property {Boolean} [navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button.
 
-  * @property {Boolean} [scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory.
 
-  * @property {Boolean} [shouldAnimate=false] <code>true</code> if the clock should attempt to advance simulation time by default, <code>false</code> otherwise.  This option takes precedence over setting {@link Viewer#clockViewModel}.
 
-  * @property {ClockViewModel} [clockViewModel=new ClockViewModel(clock)] The clock view model to use to control current time.
 
-  * @property {ProviderViewModel} [selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available base layer is used.  This value is only valid if `baseLayerPicker` is set to true.
 
-  * @property {ProviderViewModel[]} [imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker.  This value is only valid if `baseLayerPicker` is set to true.
 
-  * @property {ProviderViewModel} [selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used.  This value is only valid if `baseLayerPicker` is set to true.
 
-  * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker.  This value is only valid if `baseLayerPicker` is set to true.
 
-  * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use.  This value is only valid if `baseLayerPicker` is set to false.
 
-  * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use
 
-  * @property {SkyBox|false} [skyBox] The skybox used to render the stars.  When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added.
 
-  * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb.  Set to <code>false</code> to turn it off.
 
-  * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed.
 
-  * @property {Boolean} [useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise.
 
-  * @property {Number} [targetFrameRate] The target frame rate when using the default render loop.
 
-  * @property {Boolean} [showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs.
 
-  * @property {Boolean} [useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>.
 
-  * @property {Boolean} [automaticallyTrackDataSourceClocks=true] If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes.  Set this to false if you want to configure the clock independently.
 
-  * @property {Object} [contextOptions] Context and WebGL creation properties corresponding to <code>options</code> passed to {@link Scene}.
 
-  * @property {SceneMode} [sceneMode=SceneMode.SCENE3D] The initial scene mode.
 
-  * @property {MapProjection} [mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes.
 
-  * @property {Globe|false} [globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene.  If set to <code>false</code>, no globe will be added.
 
-  * @property {Boolean} [orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency.
 
-  * @property {Element|String} [creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}.  If not specified, the credits are added to the bottom of the widget itself.
 
-  * @property {Element|String} [creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}.  If not specified, it will appear over the widget itself.
 
-  * @property {DataSourceCollection} [dataSources=new DataSourceCollection()] The collection of data sources visualized by the widget.  If this parameter is provided,
 
-  *                               the instance is assumed to be owned by the caller and will not be destroyed when the viewer is destroyed.
 
-  * @property {Boolean} [shadows=false] Determines if shadows are cast by light sources.
 
-  * @property {ShadowMode} [terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from light sources.
 
-  * @property {MapMode2D} [mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
 
-  * @property {Boolean} [projectionPicker=false] If set to true, the ProjectionPicker widget will be created.
 
-  * @property {Boolean} [requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
 
-  * @property {Number} [maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
 
-  * @property {Number} [depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation.
 
-  * @property {Number} [msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets.
 
-  */
 
- /**
 
-  * A base widget for building applications.  It composites all of the standard Cesium widgets into one reusable package.
 
-  * The widget can always be extended by using mixins, which add functionality useful for a variety of applications.
 
-  *
 
-  * @alias Viewer
 
-  * @constructor
 
-  *
 
-  * @param {Element|String} container The DOM element or ID that will contain the widget.
 
-  * @param {Viewer.ConstructorOptions} [options] Object describing initialization options
 
-  *
 
-  * @exception {DeveloperError} Element with id "container" does not exist in the document.
 
-  * @exception {DeveloperError} options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.imageryProvider instead.
 
-  * @exception {DeveloperError} options.selectedTerrainProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.terrainProvider instead.
 
-  *
 
-  * @see Animation
 
-  * @see BaseLayerPicker
 
-  * @see CesiumWidget
 
-  * @see FullscreenButton
 
-  * @see HomeButton
 
-  * @see SceneModePicker
 
-  * @see Timeline
 
-  * @see viewerDragDropMixin
 
-  *
 
-  * @demo {@link https://sandcastle.cesium.com/index.html?src=Hello%20World.html|Cesium Sandcastle Hello World Demo}
 
-  *
 
-  * @example
 
-  * //Initialize the viewer widget with several custom options and mixins.
 
-  * const viewer = new Cesium.Viewer('cesiumContainer', {
 
-  *     //Start in Columbus Viewer
 
-  *     sceneMode : Cesium.SceneMode.COLUMBUS_VIEW,
 
-  *     //Use Cesium World Terrain
 
-  *     terrainProvider : Cesium.createWorldTerrain(),
 
-  *     //Hide the base layer picker
 
-  *     baseLayerPicker : false,
 
-  *     //Use OpenStreetMaps
 
-  *     imageryProvider : new Cesium.OpenStreetMapImageryProvider({
 
-  *         url : 'https://a.tile.openstreetmap.org/'
 
-  *     }),
 
-  *     skyBox : new Cesium.SkyBox({
 
-  *         sources : {
 
-  *           positiveX : 'stars/TychoSkymapII.t3_08192x04096_80_px.jpg',
 
-  *           negativeX : 'stars/TychoSkymapII.t3_08192x04096_80_mx.jpg',
 
-  *           positiveY : 'stars/TychoSkymapII.t3_08192x04096_80_py.jpg',
 
-  *           negativeY : 'stars/TychoSkymapII.t3_08192x04096_80_my.jpg',
 
-  *           positiveZ : 'stars/TychoSkymapII.t3_08192x04096_80_pz.jpg',
 
-  *           negativeZ : 'stars/TychoSkymapII.t3_08192x04096_80_mz.jpg'
 
-  *         }
 
-  *     }),
 
-  *     // Show Columbus View map with Web Mercator projection
 
-  *     mapProjection : new Cesium.WebMercatorProjection()
 
-  * });
 
-  *
 
-  * //Add basic drag and drop functionality
 
-  * viewer.extend(Cesium.viewerDragDropMixin);
 
-  *
 
-  * //Show a pop-up alert if we encounter an error when processing a dropped file
 
-  * viewer.dropError.addEventListener(function(dropHandler, name, error) {
 
-  *     console.log(error);
 
-  *     window.alert(error);
 
-  * });
 
-  */
 
- function Viewer(container, options) {
 
-   //>>includeStart('debug', pragmas.debug);
 
-   if (!defined(container)) {
 
-     throw new DeveloperError("container is required.");
 
-   }
 
-   //>>includeEnd('debug');
 
-   container = getElement(container);
 
-   options = defaultValue(options, defaultValue.EMPTY_OBJECT);
 
-   const createBaseLayerPicker =
 
-     (!defined(options.globe) || options.globe !== false) &&
 
-     (!defined(options.baseLayerPicker) || options.baseLayerPicker !== false);
 
-   //>>includeStart('debug', pragmas.debug);
 
-   // If not using BaseLayerPicker, selectedImageryProviderViewModel is an invalid option
 
-   if (
 
-     !createBaseLayerPicker &&
 
-     defined(options.selectedImageryProviderViewModel)
 
-   ) {
 
-     throw new DeveloperError(
 
-       "options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget. \
 
- Either specify options.imageryProvider instead or set options.baseLayerPicker to true."
 
-     );
 
-   }
 
-   // If not using BaseLayerPicker, selectedTerrainProviderViewModel is an invalid option
 
-   if (
 
-     !createBaseLayerPicker &&
 
-     defined(options.selectedTerrainProviderViewModel)
 
-   ) {
 
-     throw new DeveloperError(
 
-       "options.selectedTerrainProviderViewModel is not available when not using the BaseLayerPicker widget. \
 
- Either specify options.terrainProvider instead or set options.baseLayerPicker to true."
 
-     );
 
-   }
 
-   //>>includeEnd('debug')
 
-   const that = this;
 
-   const viewerContainer = document.createElement("div");
 
-   viewerContainer.className = "cesium-viewer";
 
-   container.appendChild(viewerContainer);
 
-   // Cesium widget container
 
-   const cesiumWidgetContainer = document.createElement("div");
 
-   cesiumWidgetContainer.className = "cesium-viewer-cesiumWidgetContainer";
 
-   viewerContainer.appendChild(cesiumWidgetContainer);
 
-   // Bottom container
 
-   const bottomContainer = document.createElement("div");
 
-   bottomContainer.className = "cesium-viewer-bottom";
 
-   viewerContainer.appendChild(bottomContainer);
 
-   const scene3DOnly = defaultValue(options.scene3DOnly, false);
 
-   let clock;
 
-   let clockViewModel;
 
-   let destroyClockViewModel = false;
 
-   if (defined(options.clockViewModel)) {
 
-     clockViewModel = options.clockViewModel;
 
-     clock = clockViewModel.clock;
 
-   } else {
 
-     clock = new Clock();
 
-     clockViewModel = new ClockViewModel(clock);
 
-     destroyClockViewModel = true;
 
-   }
 
-   if (defined(options.shouldAnimate)) {
 
-     clock.shouldAnimate = options.shouldAnimate;
 
-   }
 
-   // Cesium widget
 
-   const cesiumWidget = new CesiumWidget(cesiumWidgetContainer, {
 
-     imageryProvider:
 
-       createBaseLayerPicker || defined(options.imageryProvider)
 
-         ? false
 
-         : undefined,
 
-     clock: clock,
 
-     skyBox: options.skyBox,
 
-     skyAtmosphere: options.skyAtmosphere,
 
-     sceneMode: options.sceneMode,
 
-     mapProjection: options.mapProjection,
 
-     globe: options.globe,
 
-     orderIndependentTranslucency: options.orderIndependentTranslucency,
 
-     contextOptions: options.contextOptions,
 
-     useDefaultRenderLoop: options.useDefaultRenderLoop,
 
-     targetFrameRate: options.targetFrameRate,
 
-     showRenderLoopErrors: options.showRenderLoopErrors,
 
-     useBrowserRecommendedResolution: options.useBrowserRecommendedResolution,
 
-     creditContainer: defined(options.creditContainer)
 
-       ? options.creditContainer
 
-       : bottomContainer,
 
-     creditViewport: options.creditViewport,
 
-     scene3DOnly: scene3DOnly,
 
-     shadows: options.shadows,
 
-     terrainShadows: options.terrainShadows,
 
-     mapMode2D: options.mapMode2D,
 
-     requestRenderMode: options.requestRenderMode,
 
-     maximumRenderTimeChange: options.maximumRenderTimeChange,
 
-     depthPlaneEllipsoidOffset: options.depthPlaneEllipsoidOffset,
 
-     msaaSamples: options.msaaSamples,
 
-   });
 
-   let dataSourceCollection = options.dataSources;
 
-   let destroyDataSourceCollection = false;
 
-   if (!defined(dataSourceCollection)) {
 
-     dataSourceCollection = new DataSourceCollection();
 
-     destroyDataSourceCollection = true;
 
-   }
 
-   const scene = cesiumWidget.scene;
 
-   const dataSourceDisplay = new DataSourceDisplay({
 
-     scene: scene,
 
-     dataSourceCollection: dataSourceCollection,
 
-   });
 
-   const eventHelper = new EventHelper();
 
-   eventHelper.add(clock.onTick, Viewer.prototype._onTick, this);
 
-   eventHelper.add(scene.morphStart, Viewer.prototype._clearTrackedObject, this);
 
-   // Selection Indicator
 
-   let selectionIndicator;
 
-   if (
 
-     !defined(options.selectionIndicator) ||
 
-     options.selectionIndicator !== false
 
-   ) {
 
-     const selectionIndicatorContainer = document.createElement("div");
 
-     selectionIndicatorContainer.className =
 
-       "cesium-viewer-selectionIndicatorContainer";
 
-     viewerContainer.appendChild(selectionIndicatorContainer);
 
-     selectionIndicator = new SelectionIndicator(
 
-       selectionIndicatorContainer,
 
-       scene
 
-     );
 
-   }
 
-   // Info Box
 
-   let infoBox;
 
-   if (!defined(options.infoBox) || options.infoBox !== false) {
 
-     const infoBoxContainer = document.createElement("div");
 
-     infoBoxContainer.className = "cesium-viewer-infoBoxContainer";
 
-     viewerContainer.appendChild(infoBoxContainer);
 
-     infoBox = new InfoBox(infoBoxContainer);
 
-     const infoBoxViewModel = infoBox.viewModel;
 
-     eventHelper.add(
 
-       infoBoxViewModel.cameraClicked,
 
-       Viewer.prototype._onInfoBoxCameraClicked,
 
-       this
 
-     );
 
-     eventHelper.add(
 
-       infoBoxViewModel.closeClicked,
 
-       Viewer.prototype._onInfoBoxClockClicked,
 
-       this
 
-     );
 
-   }
 
-   // Main Toolbar
 
-   const toolbar = document.createElement("div");
 
-   toolbar.className = "cesium-viewer-toolbar";
 
-   viewerContainer.appendChild(toolbar);
 
-   // Geocoder
 
-   let geocoder;
 
-   if (!defined(options.geocoder) || options.geocoder !== false) {
 
-     const geocoderContainer = document.createElement("div");
 
-     geocoderContainer.className = "cesium-viewer-geocoderContainer";
 
-     toolbar.appendChild(geocoderContainer);
 
-     let geocoderService;
 
-     if (defined(options.geocoder) && typeof options.geocoder !== "boolean") {
 
-       geocoderService = Array.isArray(options.geocoder)
 
-         ? options.geocoder
 
-         : [options.geocoder];
 
-     }
 
-     geocoder = new Geocoder({
 
-       container: geocoderContainer,
 
-       geocoderServices: geocoderService,
 
-       scene: scene,
 
-     });
 
-     // Subscribe to search so that we can clear the trackedEntity when it is clicked.
 
-     eventHelper.add(
 
-       geocoder.viewModel.search.beforeExecute,
 
-       Viewer.prototype._clearObjects,
 
-       this
 
-     );
 
-   }
 
-   // HomeButton
 
-   let homeButton;
 
-   if (!defined(options.homeButton) || options.homeButton !== false) {
 
-     homeButton = new HomeButton(toolbar, scene);
 
-     if (defined(geocoder)) {
 
-       eventHelper.add(homeButton.viewModel.command.afterExecute, function () {
 
-         const viewModel = geocoder.viewModel;
 
-         viewModel.searchText = "";
 
-         if (viewModel.isSearchInProgress) {
 
-           viewModel.search();
 
-         }
 
-       });
 
-     }
 
-     // Subscribe to the home button beforeExecute event so that we can clear the trackedEntity.
 
-     eventHelper.add(
 
-       homeButton.viewModel.command.beforeExecute,
 
-       Viewer.prototype._clearTrackedObject,
 
-       this
 
-     );
 
-   }
 
-   // SceneModePicker
 
-   // By default, we silently disable the scene mode picker if scene3DOnly is true,
 
-   // but if sceneModePicker is explicitly set to true, throw an error.
 
-   //>>includeStart('debug', pragmas.debug);
 
-   if (options.sceneModePicker === true && scene3DOnly) {
 
-     throw new DeveloperError(
 
-       "options.sceneModePicker is not available when options.scene3DOnly is set to true."
 
-     );
 
-   }
 
-   //>>includeEnd('debug');
 
-   let sceneModePicker;
 
-   if (
 
-     !scene3DOnly &&
 
-     (!defined(options.sceneModePicker) || options.sceneModePicker !== false)
 
-   ) {
 
-     sceneModePicker = new SceneModePicker(toolbar, scene);
 
-   }
 
-   let projectionPicker;
 
-   if (options.projectionPicker) {
 
-     projectionPicker = new ProjectionPicker(toolbar, scene);
 
-   }
 
-   // BaseLayerPicker
 
-   let baseLayerPicker;
 
-   let baseLayerPickerDropDown;
 
-   if (createBaseLayerPicker) {
 
-     const imageryProviderViewModels = defaultValue(
 
-       options.imageryProviderViewModels,
 
-       createDefaultImageryProviderViewModels()
 
-     );
 
-     const terrainProviderViewModels = defaultValue(
 
-       options.terrainProviderViewModels,
 
-       createDefaultTerrainProviderViewModels()
 
-     );
 
-     baseLayerPicker = new BaseLayerPicker(toolbar, {
 
-       globe: scene.globe,
 
-       imageryProviderViewModels: imageryProviderViewModels,
 
-       selectedImageryProviderViewModel:
 
-         options.selectedImageryProviderViewModel,
 
-       terrainProviderViewModels: terrainProviderViewModels,
 
-       selectedTerrainProviderViewModel:
 
-         options.selectedTerrainProviderViewModel,
 
-     });
 
-     //Grab the dropdown for resize code.
 
-     const elements = toolbar.getElementsByClassName(
 
-       "cesium-baseLayerPicker-dropDown"
 
-     );
 
-     baseLayerPickerDropDown = elements[0];
 
-   }
 
-   // These need to be set after the BaseLayerPicker is created in order to take effect
 
-   if (defined(options.imageryProvider) && options.imageryProvider !== false) {
 
-     if (createBaseLayerPicker) {
 
-       baseLayerPicker.viewModel.selectedImagery = undefined;
 
-     }
 
-     scene.imageryLayers.removeAll();
 
-     scene.imageryLayers.addImageryProvider(options.imageryProvider);
 
-   }
 
-   if (defined(options.terrainProvider)) {
 
-     if (createBaseLayerPicker) {
 
-       baseLayerPicker.viewModel.selectedTerrain = undefined;
 
-     }
 
-     scene.terrainProvider = options.terrainProvider;
 
-   }
 
-   // Navigation Help Button
 
-   let navigationHelpButton;
 
-   if (
 
-     !defined(options.navigationHelpButton) ||
 
-     options.navigationHelpButton !== false
 
-   ) {
 
-     let showNavHelp = true;
 
-     try {
 
-       //window.localStorage is null if disabled in Firefox or undefined in browsers with implementation
 
-       if (defined(window.localStorage)) {
 
-         const hasSeenNavHelp = window.localStorage.getItem(
 
-           "cesium-hasSeenNavHelp"
 
-         );
 
-         if (defined(hasSeenNavHelp) && Boolean(hasSeenNavHelp)) {
 
-           showNavHelp = false;
 
-         } else {
 
-           window.localStorage.setItem("cesium-hasSeenNavHelp", "true");
 
-         }
 
-       }
 
-     } catch (e) {
 
-       //Accessing window.localStorage throws if disabled in Chrome
 
-       //window.localStorage.setItem throws if in Safari private browsing mode or in any browser if we are over quota.
 
-     }
 
-     navigationHelpButton = new NavigationHelpButton({
 
-       container: toolbar,
 
-       instructionsInitiallyVisible: defaultValue(
 
-         options.navigationInstructionsInitiallyVisible,
 
-         showNavHelp
 
-       ),
 
-     });
 
-   }
 
-   // Animation
 
-   let animation;
 
-   if (!defined(options.animation) || options.animation !== false) {
 
-     const animationContainer = document.createElement("div");
 
-     animationContainer.className = "cesium-viewer-animationContainer";
 
-     viewerContainer.appendChild(animationContainer);
 
-     animation = new Animation(
 
-       animationContainer,
 
-       new AnimationViewModel(clockViewModel)
 
-     );
 
-   }
 
-   // Timeline
 
-   let timeline;
 
-   if (!defined(options.timeline) || options.timeline !== false) {
 
-     const timelineContainer = document.createElement("div");
 
-     timelineContainer.className = "cesium-viewer-timelineContainer";
 
-     viewerContainer.appendChild(timelineContainer);
 
-     timeline = new Timeline(timelineContainer, clock);
 
-     timeline.addEventListener("settime", onTimelineScrubfunction, false);
 
-     timeline.zoomTo(clock.startTime, clock.stopTime);
 
-   }
 
-   // Fullscreen
 
-   let fullscreenButton;
 
-   let fullscreenSubscription;
 
-   let fullscreenContainer;
 
-   if (
 
-     !defined(options.fullscreenButton) ||
 
-     options.fullscreenButton !== false
 
-   ) {
 
-     fullscreenContainer = document.createElement("div");
 
-     fullscreenContainer.className = "cesium-viewer-fullscreenContainer";
 
-     viewerContainer.appendChild(fullscreenContainer);
 
-     fullscreenButton = new FullscreenButton(
 
-       fullscreenContainer,
 
-       options.fullscreenElement
 
-     );
 
-     //Subscribe to fullscreenButton.viewModel.isFullscreenEnabled so
 
-     //that we can hide/show the button as well as size the timeline.
 
-     fullscreenSubscription = subscribeAndEvaluate(
 
-       fullscreenButton.viewModel,
 
-       "isFullscreenEnabled",
 
-       function (isFullscreenEnabled) {
 
-         fullscreenContainer.style.display = isFullscreenEnabled
 
-           ? "block"
 
-           : "none";
 
-         if (defined(timeline)) {
 
-           timeline.container.style.right = `${fullscreenContainer.clientWidth}px`;
 
-           timeline.resize();
 
-         }
 
-       }
 
-     );
 
-   }
 
-   // VR
 
-   let vrButton;
 
-   let vrSubscription;
 
-   let vrModeSubscription;
 
-   if (options.vrButton) {
 
-     const vrContainer = document.createElement("div");
 
-     vrContainer.className = "cesium-viewer-vrContainer";
 
-     viewerContainer.appendChild(vrContainer);
 
-     vrButton = new VRButton(vrContainer, scene, options.fullScreenElement);
 
-     vrSubscription = subscribeAndEvaluate(
 
-       vrButton.viewModel,
 
-       "isVREnabled",
 
-       function (isVREnabled) {
 
-         vrContainer.style.display = isVREnabled ? "block" : "none";
 
-         if (defined(fullscreenButton)) {
 
-           vrContainer.style.right = `${fullscreenContainer.clientWidth}px`;
 
-         }
 
-         if (defined(timeline)) {
 
-           timeline.container.style.right = `${vrContainer.clientWidth}px`;
 
-           timeline.resize();
 
-         }
 
-       }
 
-     );
 
-     vrModeSubscription = subscribeAndEvaluate(
 
-       vrButton.viewModel,
 
-       "isVRMode",
 
-       function (isVRMode) {
 
-         enableVRUI(that, isVRMode);
 
-       }
 
-     );
 
-   }
 
-   //Assign all properties to this instance.  No "this" assignments should
 
-   //take place above this line.
 
-   this._baseLayerPickerDropDown = baseLayerPickerDropDown;
 
-   this._fullscreenSubscription = fullscreenSubscription;
 
-   this._vrSubscription = vrSubscription;
 
-   this._vrModeSubscription = vrModeSubscription;
 
-   this._dataSourceChangedListeners = {};
 
-   this._automaticallyTrackDataSourceClocks = defaultValue(
 
-     options.automaticallyTrackDataSourceClocks,
 
-     true
 
-   );
 
-   this._container = container;
 
-   this._bottomContainer = bottomContainer;
 
-   this._element = viewerContainer;
 
-   this._cesiumWidget = cesiumWidget;
 
-   this._selectionIndicator = selectionIndicator;
 
-   this._infoBox = infoBox;
 
-   this._dataSourceCollection = dataSourceCollection;
 
-   this._destroyDataSourceCollection = destroyDataSourceCollection;
 
-   this._dataSourceDisplay = dataSourceDisplay;
 
-   this._clockViewModel = clockViewModel;
 
-   this._destroyClockViewModel = destroyClockViewModel;
 
-   this._toolbar = toolbar;
 
-   this._homeButton = homeButton;
 
-   this._sceneModePicker = sceneModePicker;
 
-   this._projectionPicker = projectionPicker;
 
-   this._baseLayerPicker = baseLayerPicker;
 
-   this._navigationHelpButton = navigationHelpButton;
 
-   this._animation = animation;
 
-   this._timeline = timeline;
 
-   this._fullscreenButton = fullscreenButton;
 
-   this._vrButton = vrButton;
 
-   this._geocoder = geocoder;
 
-   this._eventHelper = eventHelper;
 
-   this._lastWidth = 0;
 
-   this._lastHeight = 0;
 
-   this._allowDataSourcesToSuspendAnimation = true;
 
-   this._entityView = undefined;
 
-   this._enableInfoOrSelection = defined(infoBox) || defined(selectionIndicator);
 
-   this._clockTrackedDataSource = undefined;
 
-   this._trackedEntity = undefined;
 
-   this._needTrackedEntityUpdate = false;
 
-   this._selectedEntity = undefined;
 
-   this._zoomIsFlight = false;
 
-   this._zoomTarget = undefined;
 
-   this._zoomPromise = undefined;
 
-   this._zoomOptions = undefined;
 
-   this._selectedEntityChanged = new Event();
 
-   this._trackedEntityChanged = new Event();
 
-   knockout.track(this, [
 
-     "_trackedEntity",
 
-     "_selectedEntity",
 
-     "_clockTrackedDataSource",
 
-   ]);
 
-   //Listen to data source events in order to track clock changes.
 
-   eventHelper.add(
 
-     dataSourceCollection.dataSourceAdded,
 
-     Viewer.prototype._onDataSourceAdded,
 
-     this
 
-   );
 
-   eventHelper.add(
 
-     dataSourceCollection.dataSourceRemoved,
 
-     Viewer.prototype._onDataSourceRemoved,
 
-     this
 
-   );
 
-   // Prior to each render, check if anything needs to be resized.
 
-   eventHelper.add(scene.postUpdate, Viewer.prototype.resize, this);
 
-   eventHelper.add(scene.postRender, Viewer.prototype._postRender, this);
 
-   // We need to subscribe to the data sources and collections so that we can clear the
 
-   // tracked object when it is removed from the scene.
 
-   // Subscribe to current data sources
 
-   const dataSourceLength = dataSourceCollection.length;
 
-   for (let i = 0; i < dataSourceLength; i++) {
 
-     this._dataSourceAdded(dataSourceCollection, dataSourceCollection.get(i));
 
-   }
 
-   this._dataSourceAdded(undefined, dataSourceDisplay.defaultDataSource);
 
-   // Hook up events so that we can subscribe to future sources.
 
-   eventHelper.add(
 
-     dataSourceCollection.dataSourceAdded,
 
-     Viewer.prototype._dataSourceAdded,
 
-     this
 
-   );
 
-   eventHelper.add(
 
-     dataSourceCollection.dataSourceRemoved,
 
-     Viewer.prototype._dataSourceRemoved,
 
-     this
 
-   );
 
-   // Subscribe to left clicks and zoom to the picked object.
 
-   function pickAndTrackObject(e) {
 
-     const entity = pickEntity(that, e);
 
-     if (defined(entity)) {
 
-       //Only track the entity if it has a valid position at the current time.
 
-       if (
 
-         Property.getValueOrUndefined(entity.position, that.clock.currentTime)
 
-       ) {
 
-         that.trackedEntity = entity;
 
-       } else {
 
-         that.zoomTo(entity);
 
-       }
 
-     } else if (defined(that.trackedEntity)) {
 
-       that.trackedEntity = undefined;
 
-     }
 
-   }
 
-   function pickAndSelectObject(e) {
 
-     that.selectedEntity = pickEntity(that, e);
 
-   }
 
-   cesiumWidget.screenSpaceEventHandler.setInputAction(
 
-     pickAndSelectObject,
 
-     ScreenSpaceEventType.LEFT_CLICK
 
-   );
 
-   cesiumWidget.screenSpaceEventHandler.setInputAction(
 
-     pickAndTrackObject,
 
-     ScreenSpaceEventType.LEFT_DOUBLE_CLICK
 
-   );
 
- }
 
- Object.defineProperties(Viewer.prototype, {
 
-   /**
 
-    * Gets the parent container.
 
-    * @memberof Viewer.prototype
 
-    * @type {Element}
 
-    * @readonly
 
-    */
 
-   container: {
 
-     get: function () {
 
-       return this._container;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the DOM element for the area at the bottom of the window containing the
 
-    * {@link CreditDisplay} and potentially other things.
 
-    * @memberof Viewer.prototype
 
-    * @type {Element}
 
-    * @readonly
 
-    */
 
-   bottomContainer: {
 
-     get: function () {
 
-       return this._bottomContainer;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the CesiumWidget.
 
-    * @memberof Viewer.prototype
 
-    * @type {CesiumWidget}
 
-    * @readonly
 
-    */
 
-   cesiumWidget: {
 
-     get: function () {
 
-       return this._cesiumWidget;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the selection indicator.
 
-    * @memberof Viewer.prototype
 
-    * @type {SelectionIndicator}
 
-    * @readonly
 
-    */
 
-   selectionIndicator: {
 
-     get: function () {
 
-       return this._selectionIndicator;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the info box.
 
-    * @memberof Viewer.prototype
 
-    * @type {InfoBox}
 
-    * @readonly
 
-    */
 
-   infoBox: {
 
-     get: function () {
 
-       return this._infoBox;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the Geocoder.
 
-    * @memberof Viewer.prototype
 
-    * @type {Geocoder}
 
-    * @readonly
 
-    */
 
-   geocoder: {
 
-     get: function () {
 
-       return this._geocoder;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the HomeButton.
 
-    * @memberof Viewer.prototype
 
-    * @type {HomeButton}
 
-    * @readonly
 
-    */
 
-   homeButton: {
 
-     get: function () {
 
-       return this._homeButton;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the SceneModePicker.
 
-    * @memberof Viewer.prototype
 
-    * @type {SceneModePicker}
 
-    * @readonly
 
-    */
 
-   sceneModePicker: {
 
-     get: function () {
 
-       return this._sceneModePicker;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the ProjectionPicker.
 
-    * @memberof Viewer.prototype
 
-    * @type {ProjectionPicker}
 
-    * @readonly
 
-    */
 
-   projectionPicker: {
 
-     get: function () {
 
-       return this._projectionPicker;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the BaseLayerPicker.
 
-    * @memberof Viewer.prototype
 
-    * @type {BaseLayerPicker}
 
-    * @readonly
 
-    */
 
-   baseLayerPicker: {
 
-     get: function () {
 
-       return this._baseLayerPicker;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the NavigationHelpButton.
 
-    * @memberof Viewer.prototype
 
-    * @type {NavigationHelpButton}
 
-    * @readonly
 
-    */
 
-   navigationHelpButton: {
 
-     get: function () {
 
-       return this._navigationHelpButton;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the Animation widget.
 
-    * @memberof Viewer.prototype
 
-    * @type {Animation}
 
-    * @readonly
 
-    */
 
-   animation: {
 
-     get: function () {
 
-       return this._animation;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the Timeline widget.
 
-    * @memberof Viewer.prototype
 
-    * @type {Timeline}
 
-    * @readonly
 
-    */
 
-   timeline: {
 
-     get: function () {
 
-       return this._timeline;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the FullscreenButton.
 
-    * @memberof Viewer.prototype
 
-    * @type {FullscreenButton}
 
-    * @readonly
 
-    */
 
-   fullscreenButton: {
 
-     get: function () {
 
-       return this._fullscreenButton;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the VRButton.
 
-    * @memberof Viewer.prototype
 
-    * @type {VRButton}
 
-    * @readonly
 
-    */
 
-   vrButton: {
 
-     get: function () {
 
-       return this._vrButton;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the display used for {@link DataSource} visualization.
 
-    * @memberof Viewer.prototype
 
-    * @type {DataSourceDisplay}
 
-    * @readonly
 
-    */
 
-   dataSourceDisplay: {
 
-     get: function () {
 
-       return this._dataSourceDisplay;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the collection of entities not tied to a particular data source.
 
-    * This is a shortcut to [dataSourceDisplay.defaultDataSource.entities]{@link Viewer#dataSourceDisplay}.
 
-    * @memberof Viewer.prototype
 
-    * @type {EntityCollection}
 
-    * @readonly
 
-    */
 
-   entities: {
 
-     get: function () {
 
-       return this._dataSourceDisplay.defaultDataSource.entities;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the set of {@link DataSource} instances to be visualized.
 
-    * @memberof Viewer.prototype
 
-    * @type {DataSourceCollection}
 
-    * @readonly
 
-    */
 
-   dataSources: {
 
-     get: function () {
 
-       return this._dataSourceCollection;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the canvas.
 
-    * @memberof Viewer.prototype
 
-    * @type {HTMLCanvasElement}
 
-    * @readonly
 
-    */
 
-   canvas: {
 
-     get: function () {
 
-       return this._cesiumWidget.canvas;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the scene.
 
-    * @memberof Viewer.prototype
 
-    * @type {Scene}
 
-    * @readonly
 
-    */
 
-   scene: {
 
-     get: function () {
 
-       return this._cesiumWidget.scene;
 
-     },
 
-   },
 
-   /**
 
-    * Determines if shadows are cast by light sources.
 
-    * @memberof Viewer.prototype
 
-    * @type {Boolean}
 
-    */
 
-   shadows: {
 
-     get: function () {
 
-       return this.scene.shadowMap.enabled;
 
-     },
 
-     set: function (value) {
 
-       this.scene.shadowMap.enabled = value;
 
-     },
 
-   },
 
-   /**
 
-    * Determines if the terrain casts or shadows from light sources.
 
-    * @memberof Viewer.prototype
 
-    * @type {ShadowMode}
 
-    */
 
-   terrainShadows: {
 
-     get: function () {
 
-       return this.scene.globe.shadows;
 
-     },
 
-     set: function (value) {
 
-       this.scene.globe.shadows = value;
 
-     },
 
-   },
 
-   /**
 
-    * Get the scene's shadow map
 
-    * @memberof Viewer.prototype
 
-    * @type {ShadowMap}
 
-    * @readonly
 
-    */
 
-   shadowMap: {
 
-     get: function () {
 
-       return this.scene.shadowMap;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the collection of image layers that will be rendered on the globe.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {ImageryLayerCollection}
 
-    * @readonly
 
-    */
 
-   imageryLayers: {
 
-     get: function () {
 
-       return this.scene.imageryLayers;
 
-     },
 
-   },
 
-   /**
 
-    * The terrain provider providing surface geometry for the globe.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {TerrainProvider}
 
-    */
 
-   terrainProvider: {
 
-     get: function () {
 
-       return this.scene.terrainProvider;
 
-     },
 
-     set: function (terrainProvider) {
 
-       this.scene.terrainProvider = terrainProvider;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the camera.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Camera}
 
-    * @readonly
 
-    */
 
-   camera: {
 
-     get: function () {
 
-       return this.scene.camera;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the post-process stages.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {PostProcessStageCollection}
 
-    * @readonly
 
-    */
 
-   postProcessStages: {
 
-     get: function () {
 
-       return this.scene.postProcessStages;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the clock.
 
-    * @memberof Viewer.prototype
 
-    * @type {Clock}
 
-    * @readonly
 
-    */
 
-   clock: {
 
-     get: function () {
 
-       return this._clockViewModel.clock;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the clock view model.
 
-    * @memberof Viewer.prototype
 
-    * @type {ClockViewModel}
 
-    * @readonly
 
-    */
 
-   clockViewModel: {
 
-     get: function () {
 
-       return this._clockViewModel;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the screen space event handler.
 
-    * @memberof Viewer.prototype
 
-    * @type {ScreenSpaceEventHandler}
 
-    * @readonly
 
-    */
 
-   screenSpaceEventHandler: {
 
-     get: function () {
 
-       return this._cesiumWidget.screenSpaceEventHandler;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets the target frame rate of the widget when <code>useDefaultRenderLoop</code>
 
-    * is true. If undefined, the browser's {@link requestAnimationFrame} implementation
 
-    * determines the frame rate.  If defined, this value must be greater than 0.  A value higher
 
-    * than the underlying requestAnimationFrame implementation will have no effect.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Number}
 
-    */
 
-   targetFrameRate: {
 
-     get: function () {
 
-       return this._cesiumWidget.targetFrameRate;
 
-     },
 
-     set: function (value) {
 
-       this._cesiumWidget.targetFrameRate = value;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets whether or not this widget should control the render loop.
 
-    * If set to true the widget will use {@link requestAnimationFrame} to
 
-    * perform rendering and resizing of the widget, as well as drive the
 
-    * simulation clock. If set to false, you must manually call the
 
-    * <code>resize</code>, <code>render</code> methods
 
-    * as part of a custom render loop.  If an error occurs during rendering, {@link Scene}'s
 
-    * <code>renderError</code> event will be raised and this property
 
-    * will be set to false.  It must be set back to true to continue rendering
 
-    * after the error.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Boolean}
 
-    */
 
-   useDefaultRenderLoop: {
 
-     get: function () {
 
-       return this._cesiumWidget.useDefaultRenderLoop;
 
-     },
 
-     set: function (value) {
 
-       this._cesiumWidget.useDefaultRenderLoop = value;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets a scaling factor for rendering resolution.  Values less than 1.0 can improve
 
-    * performance on less powerful devices while values greater than 1.0 will render at a higher
 
-    * resolution and then scale down, resulting in improved visual fidelity.
 
-    * For example, if the widget is laid out at a size of 640x480, setting this value to 0.5
 
-    * will cause the scene to be rendered at 320x240 and then scaled up while setting
 
-    * it to 2.0 will cause the scene to be rendered at 1280x960 and then scaled down.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Number}
 
-    * @default 1.0
 
-    */
 
-   resolutionScale: {
 
-     get: function () {
 
-       return this._cesiumWidget.resolutionScale;
 
-     },
 
-     set: function (value) {
 
-       this._cesiumWidget.resolutionScale = value;
 
-     },
 
-   },
 
-   /**
 
-    * Boolean flag indicating if the browser's recommended resolution is used.
 
-    * If true, the browser's device pixel ratio is ignored and 1.0 is used instead,
 
-    * effectively rendering based on CSS pixels instead of device pixels. This can improve
 
-    * performance on less powerful devices that have high pixel density. When false, rendering
 
-    * will be in device pixels. {@link Viewer#resolutionScale} will still take effect whether
 
-    * this flag is true or false.
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Boolean}
 
-    * @default true
 
-    */
 
-   useBrowserRecommendedResolution: {
 
-     get: function () {
 
-       return this._cesiumWidget.useBrowserRecommendedResolution;
 
-     },
 
-     set: function (value) {
 
-       this._cesiumWidget.useBrowserRecommendedResolution = value;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets whether or not data sources can temporarily pause
 
-    * animation in order to avoid showing an incomplete picture to the user.
 
-    * For example, if asynchronous primitives are being processed in the
 
-    * background, the clock will not advance until the geometry is ready.
 
-    *
 
-    * @memberof Viewer.prototype
 
-    *
 
-    * @type {Boolean}
 
-    */
 
-   allowDataSourcesToSuspendAnimation: {
 
-     get: function () {
 
-       return this._allowDataSourcesToSuspendAnimation;
 
-     },
 
-     set: function (value) {
 
-       this._allowDataSourcesToSuspendAnimation = value;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets the Entity instance currently being tracked by the camera.
 
-    * @memberof Viewer.prototype
 
-    * @type {Entity | undefined}
 
-    */
 
-   trackedEntity: {
 
-     get: function () {
 
-       return this._trackedEntity;
 
-     },
 
-     set: function (value) {
 
-       if (this._trackedEntity !== value) {
 
-         this._trackedEntity = value;
 
-         //Cancel any pending zoom
 
-         cancelZoom(this);
 
-         const scene = this.scene;
 
-         const sceneMode = scene.mode;
 
-         //Stop tracking
 
-         if (!defined(value) || !defined(value.position)) {
 
-           this._needTrackedEntityUpdate = false;
 
-           if (
 
-             sceneMode === SceneMode.COLUMBUS_VIEW ||
 
-             sceneMode === SceneMode.SCENE2D
 
-           ) {
 
-             scene.screenSpaceCameraController.enableTranslate = true;
 
-           }
 
-           if (
 
-             sceneMode === SceneMode.COLUMBUS_VIEW ||
 
-             sceneMode === SceneMode.SCENE3D
 
-           ) {
 
-             scene.screenSpaceCameraController.enableTilt = true;
 
-           }
 
-           this._entityView = undefined;
 
-           this.camera.lookAtTransform(Matrix4.IDENTITY);
 
-         } else {
 
-           //We can't start tracking immediately, so we set a flag and start tracking
 
-           //when the bounding sphere is ready (most likely next frame).
 
-           this._needTrackedEntityUpdate = true;
 
-         }
 
-         this._trackedEntityChanged.raiseEvent(value);
 
-         this.scene.requestRender();
 
-       }
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets the object instance for which to display a selection indicator.
 
-    *
 
-    * If a user interactively picks a Cesium3DTilesFeature instance, then this property
 
-    * will contain a transient Entity instance with a property named "feature" that is
 
-    * the instance that was picked.
 
-    * @memberof Viewer.prototype
 
-    * @type {Entity | undefined}
 
-    */
 
-   selectedEntity: {
 
-     get: function () {
 
-       return this._selectedEntity;
 
-     },
 
-     set: function (value) {
 
-       if (this._selectedEntity !== value) {
 
-         this._selectedEntity = value;
 
-         const selectionIndicatorViewModel = defined(this._selectionIndicator)
 
-           ? this._selectionIndicator.viewModel
 
-           : undefined;
 
-         if (defined(value)) {
 
-           if (defined(selectionIndicatorViewModel)) {
 
-             selectionIndicatorViewModel.animateAppear();
 
-           }
 
-         } else if (defined(selectionIndicatorViewModel)) {
 
-           // Leave the info text in place here, it is needed during the exit animation.
 
-           selectionIndicatorViewModel.animateDepart();
 
-         }
 
-         this._selectedEntityChanged.raiseEvent(value);
 
-       }
 
-     },
 
-   },
 
-   /**
 
-    * Gets the event that is raised when the selected entity changes.
 
-    * @memberof Viewer.prototype
 
-    * @type {Event}
 
-    * @readonly
 
-    */
 
-   selectedEntityChanged: {
 
-     get: function () {
 
-       return this._selectedEntityChanged;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the event that is raised when the tracked entity changes.
 
-    * @memberof Viewer.prototype
 
-    * @type {Event}
 
-    * @readonly
 
-    */
 
-   trackedEntityChanged: {
 
-     get: function () {
 
-       return this._trackedEntityChanged;
 
-     },
 
-   },
 
-   /**
 
-    * Gets or sets the data source to track with the viewer's clock.
 
-    * @memberof Viewer.prototype
 
-    * @type {DataSource}
 
-    */
 
-   clockTrackedDataSource: {
 
-     get: function () {
 
-       return this._clockTrackedDataSource;
 
-     },
 
-     set: function (value) {
 
-       if (this._clockTrackedDataSource !== value) {
 
-         this._clockTrackedDataSource = value;
 
-         trackDataSourceClock(this._timeline, this.clock, value);
 
-       }
 
-     },
 
-   },
 
- });
 
- /**
 
-  * Extends the base viewer functionality with the provided mixin.
 
-  * A mixin may add additional properties, functions, or other behavior
 
-  * to the provided viewer instance.
 
-  *
 
-  * @param {Viewer.ViewerMixin} mixin The Viewer mixin to add to this instance.
 
-  * @param {Object} [options] The options object to be passed to the mixin function.
 
-  *
 
-  * @see viewerDragDropMixin
 
-  */
 
- Viewer.prototype.extend = function (mixin, options) {
 
-   //>>includeStart('debug', pragmas.debug);
 
-   if (!defined(mixin)) {
 
-     throw new DeveloperError("mixin is required.");
 
-   }
 
-   //>>includeEnd('debug')
 
-   mixin(this, options);
 
- };
 
- /**
 
-  * Resizes the widget to match the container size.
 
-  * This function is called automatically as needed unless
 
-  * <code>useDefaultRenderLoop</code> is set to false.
 
-  */
 
- Viewer.prototype.resize = function () {
 
-   const cesiumWidget = this._cesiumWidget;
 
-   const container = this._container;
 
-   const width = container.clientWidth;
 
-   const height = container.clientHeight;
 
-   const animationExists = defined(this._animation);
 
-   const timelineExists = defined(this._timeline);
 
-   cesiumWidget.resize();
 
-   if (width === this._lastWidth && height === this._lastHeight) {
 
-     return;
 
-   }
 
-   const panelMaxHeight = height - 125;
 
-   const baseLayerPickerDropDown = this._baseLayerPickerDropDown;
 
-   if (defined(baseLayerPickerDropDown)) {
 
-     baseLayerPickerDropDown.style.maxHeight = `${panelMaxHeight}px`;
 
-   }
 
-   if (defined(this._geocoder)) {
 
-     const geocoderSuggestions = this._geocoder.searchSuggestionsContainer;
 
-     geocoderSuggestions.style.maxHeight = `${panelMaxHeight}px`;
 
-   }
 
-   if (defined(this._infoBox)) {
 
-     this._infoBox.viewModel.maxHeight = panelMaxHeight;
 
-   }
 
-   const timeline = this._timeline;
 
-   let animationContainer;
 
-   let animationWidth = 0;
 
-   let creditLeft = 0;
 
-   let creditBottom = 0;
 
-   if (
 
-     animationExists &&
 
-     window.getComputedStyle(this._animation.container).visibility !== "hidden"
 
-   ) {
 
-     const lastWidth = this._lastWidth;
 
-     animationContainer = this._animation.container;
 
-     if (width > 900) {
 
-       animationWidth = 169;
 
-       if (lastWidth <= 900) {
 
-         animationContainer.style.width = "169px";
 
-         animationContainer.style.height = "112px";
 
-         this._animation.resize();
 
-       }
 
-     } else if (width >= 600) {
 
-       animationWidth = 136;
 
-       if (lastWidth < 600 || lastWidth > 900) {
 
-         animationContainer.style.width = "136px";
 
-         animationContainer.style.height = "90px";
 
-         this._animation.resize();
 
-       }
 
-     } else {
 
-       animationWidth = 106;
 
-       if (lastWidth > 600 || lastWidth === 0) {
 
-         animationContainer.style.width = "106px";
 
-         animationContainer.style.height = "70px";
 
-         this._animation.resize();
 
-       }
 
-     }
 
-     creditLeft = animationWidth + 5;
 
-   }
 
-   if (
 
-     timelineExists &&
 
-     window.getComputedStyle(this._timeline.container).visibility !== "hidden"
 
-   ) {
 
-     const fullscreenButton = this._fullscreenButton;
 
-     const vrButton = this._vrButton;
 
-     const timelineContainer = timeline.container;
 
-     const timelineStyle = timelineContainer.style;
 
-     creditBottom = timelineContainer.clientHeight + 3;
 
-     timelineStyle.left = `${animationWidth}px`;
 
-     let pixels = 0;
 
-     if (defined(fullscreenButton)) {
 
-       pixels += fullscreenButton.container.clientWidth;
 
-     }
 
-     if (defined(vrButton)) {
 
-       pixels += vrButton.container.clientWidth;
 
-     }
 
-     timelineStyle.right = `${pixels}px`;
 
-     timeline.resize();
 
-   }
 
-   this._bottomContainer.style.left = `${creditLeft}px`;
 
-   this._bottomContainer.style.bottom = `${creditBottom}px`;
 
-   this._lastWidth = width;
 
-   this._lastHeight = height;
 
- };
 
- /**
 
-  * This forces the widget to re-think its layout, including
 
-  * widget sizes and credit placement.
 
-  */
 
- Viewer.prototype.forceResize = function () {
 
-   this._lastWidth = 0;
 
-   this.resize();
 
- };
 
- /**
 
-  * Renders the scene.  This function is called automatically
 
-  * unless <code>useDefaultRenderLoop</code> is set to false;
 
-  */
 
- Viewer.prototype.render = function () {
 
-   this._cesiumWidget.render();
 
- };
 
- /**
 
-  * @returns {Boolean} true if the object has been destroyed, false otherwise.
 
-  */
 
- Viewer.prototype.isDestroyed = function () {
 
-   return false;
 
- };
 
- /**
 
-  * Destroys the widget.  Should be called if permanently
 
-  * removing the widget from layout.
 
-  */
 
- Viewer.prototype.destroy = function () {
 
-   let i;
 
-   this.screenSpaceEventHandler.removeInputAction(
 
-     ScreenSpaceEventType.LEFT_CLICK
 
-   );
 
-   this.screenSpaceEventHandler.removeInputAction(
 
-     ScreenSpaceEventType.LEFT_DOUBLE_CLICK
 
-   );
 
-   // Unsubscribe from data sources
 
-   const dataSources = this.dataSources;
 
-   const dataSourceLength = dataSources.length;
 
-   for (i = 0; i < dataSourceLength; i++) {
 
-     this._dataSourceRemoved(dataSources, dataSources.get(i));
 
-   }
 
-   this._dataSourceRemoved(undefined, this._dataSourceDisplay.defaultDataSource);
 
-   this._container.removeChild(this._element);
 
-   this._element.removeChild(this._toolbar);
 
-   this._eventHelper.removeAll();
 
-   if (defined(this._geocoder)) {
 
-     this._geocoder = this._geocoder.destroy();
 
-   }
 
-   if (defined(this._homeButton)) {
 
-     this._homeButton = this._homeButton.destroy();
 
-   }
 
-   if (defined(this._sceneModePicker)) {
 
-     this._sceneModePicker = this._sceneModePicker.destroy();
 
-   }
 
-   if (defined(this._projectionPicker)) {
 
-     this._projectionPicker = this._projectionPicker.destroy();
 
-   }
 
-   if (defined(this._baseLayerPicker)) {
 
-     this._baseLayerPicker = this._baseLayerPicker.destroy();
 
-   }
 
-   if (defined(this._animation)) {
 
-     this._element.removeChild(this._animation.container);
 
-     this._animation = this._animation.destroy();
 
-   }
 
-   if (defined(this._timeline)) {
 
-     this._timeline.removeEventListener(
 
-       "settime",
 
-       onTimelineScrubfunction,
 
-       false
 
-     );
 
-     this._element.removeChild(this._timeline.container);
 
-     this._timeline = this._timeline.destroy();
 
-   }
 
-   if (defined(this._fullscreenButton)) {
 
-     this._fullscreenSubscription.dispose();
 
-     this._element.removeChild(this._fullscreenButton.container);
 
-     this._fullscreenButton = this._fullscreenButton.destroy();
 
-   }
 
-   if (defined(this._vrButton)) {
 
-     this._vrSubscription.dispose();
 
-     this._vrModeSubscription.dispose();
 
-     this._element.removeChild(this._vrButton.container);
 
-     this._vrButton = this._vrButton.destroy();
 
-   }
 
-   if (defined(this._infoBox)) {
 
-     this._element.removeChild(this._infoBox.container);
 
-     this._infoBox = this._infoBox.destroy();
 
-   }
 
-   if (defined(this._selectionIndicator)) {
 
-     this._element.removeChild(this._selectionIndicator.container);
 
-     this._selectionIndicator = this._selectionIndicator.destroy();
 
-   }
 
-   if (this._destroyClockViewModel) {
 
-     this._clockViewModel = this._clockViewModel.destroy();
 
-   }
 
-   this._dataSourceDisplay = this._dataSourceDisplay.destroy();
 
-   this._cesiumWidget = this._cesiumWidget.destroy();
 
-   if (this._destroyDataSourceCollection) {
 
-     this._dataSourceCollection = this._dataSourceCollection.destroy();
 
-   }
 
-   return destroyObject(this);
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._dataSourceAdded = function (
 
-   dataSourceCollection,
 
-   dataSource
 
- ) {
 
-   const entityCollection = dataSource.entities;
 
-   entityCollection.collectionChanged.addEventListener(
 
-     Viewer.prototype._onEntityCollectionChanged,
 
-     this
 
-   );
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._dataSourceRemoved = function (
 
-   dataSourceCollection,
 
-   dataSource
 
- ) {
 
-   const entityCollection = dataSource.entities;
 
-   entityCollection.collectionChanged.removeEventListener(
 
-     Viewer.prototype._onEntityCollectionChanged,
 
-     this
 
-   );
 
-   if (defined(this.trackedEntity)) {
 
-     if (
 
-       entityCollection.getById(this.trackedEntity.id) === this.trackedEntity
 
-     ) {
 
-       this.trackedEntity = undefined;
 
-     }
 
-   }
 
-   if (defined(this.selectedEntity)) {
 
-     if (
 
-       entityCollection.getById(this.selectedEntity.id) === this.selectedEntity
 
-     ) {
 
-       this.selectedEntity = undefined;
 
-     }
 
-   }
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onTick = function (clock) {
 
-   const time = clock.currentTime;
 
-   const isUpdated = this._dataSourceDisplay.update(time);
 
-   if (this._allowDataSourcesToSuspendAnimation) {
 
-     this._clockViewModel.canAnimate = isUpdated;
 
-   }
 
-   const entityView = this._entityView;
 
-   if (defined(entityView)) {
 
-     const trackedEntity = this._trackedEntity;
 
-     const trackedState = this._dataSourceDisplay.getBoundingSphere(
 
-       trackedEntity,
 
-       false,
 
-       boundingSphereScratch
 
-     );
 
-     if (trackedState === BoundingSphereState.DONE) {
 
-       entityView.update(time, boundingSphereScratch);
 
-     }
 
-   }
 
-   let position;
 
-   let enableCamera = false;
 
-   const selectedEntity = this.selectedEntity;
 
-   const showSelection = defined(selectedEntity) && this._enableInfoOrSelection;
 
-   if (
 
-     showSelection &&
 
-     selectedEntity.isShowing &&
 
-     selectedEntity.isAvailable(time)
 
-   ) {
 
-     const state = this._dataSourceDisplay.getBoundingSphere(
 
-       selectedEntity,
 
-       true,
 
-       boundingSphereScratch
 
-     );
 
-     if (state !== BoundingSphereState.FAILED) {
 
-       position = boundingSphereScratch.center;
 
-     } else if (defined(selectedEntity.position)) {
 
-       position = selectedEntity.position.getValue(time, position);
 
-     }
 
-     enableCamera = defined(position);
 
-   }
 
-   const selectionIndicatorViewModel = defined(this._selectionIndicator)
 
-     ? this._selectionIndicator.viewModel
 
-     : undefined;
 
-   if (defined(selectionIndicatorViewModel)) {
 
-     selectionIndicatorViewModel.position = Cartesian3.clone(
 
-       position,
 
-       selectionIndicatorViewModel.position
 
-     );
 
-     selectionIndicatorViewModel.showSelection = showSelection && enableCamera;
 
-     selectionIndicatorViewModel.update();
 
-   }
 
-   const infoBoxViewModel = defined(this._infoBox)
 
-     ? this._infoBox.viewModel
 
-     : undefined;
 
-   if (defined(infoBoxViewModel)) {
 
-     infoBoxViewModel.showInfo = showSelection;
 
-     infoBoxViewModel.enableCamera = enableCamera;
 
-     infoBoxViewModel.isCameraTracking =
 
-       this.trackedEntity === this.selectedEntity;
 
-     if (showSelection) {
 
-       infoBoxViewModel.titleText = defaultValue(
 
-         selectedEntity.name,
 
-         selectedEntity.id
 
-       );
 
-       infoBoxViewModel.description = Property.getValueOrDefault(
 
-         selectedEntity.description,
 
-         time,
 
-         ""
 
-       );
 
-     } else {
 
-       infoBoxViewModel.titleText = "";
 
-       infoBoxViewModel.description = "";
 
-     }
 
-   }
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onEntityCollectionChanged = function (
 
-   collection,
 
-   added,
 
-   removed
 
- ) {
 
-   const length = removed.length;
 
-   for (let i = 0; i < length; i++) {
 
-     const removedObject = removed[i];
 
-     if (this.trackedEntity === removedObject) {
 
-       this.trackedEntity = undefined;
 
-     }
 
-     if (this.selectedEntity === removedObject) {
 
-       this.selectedEntity = undefined;
 
-     }
 
-   }
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onInfoBoxCameraClicked = function (infoBoxViewModel) {
 
-   if (
 
-     infoBoxViewModel.isCameraTracking &&
 
-     this.trackedEntity === this.selectedEntity
 
-   ) {
 
-     this.trackedEntity = undefined;
 
-   } else {
 
-     const selectedEntity = this.selectedEntity;
 
-     const position = selectedEntity.position;
 
-     if (defined(position)) {
 
-       this.trackedEntity = this.selectedEntity;
 
-     } else {
 
-       this.zoomTo(this.selectedEntity);
 
-     }
 
-   }
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._clearTrackedObject = function () {
 
-   this.trackedEntity = undefined;
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onInfoBoxClockClicked = function (infoBoxViewModel) {
 
-   this.selectedEntity = undefined;
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._clearObjects = function () {
 
-   this.trackedEntity = undefined;
 
-   this.selectedEntity = undefined;
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onDataSourceChanged = function (dataSource) {
 
-   if (this.clockTrackedDataSource === dataSource) {
 
-     trackDataSourceClock(this.timeline, this.clock, dataSource);
 
-   }
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onDataSourceAdded = function (
 
-   dataSourceCollection,
 
-   dataSource
 
- ) {
 
-   if (this._automaticallyTrackDataSourceClocks) {
 
-     this.clockTrackedDataSource = dataSource;
 
-   }
 
-   const id = dataSource.entities.id;
 
-   const removalFunc = this._eventHelper.add(
 
-     dataSource.changedEvent,
 
-     Viewer.prototype._onDataSourceChanged,
 
-     this
 
-   );
 
-   this._dataSourceChangedListeners[id] = removalFunc;
 
- };
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._onDataSourceRemoved = function (
 
-   dataSourceCollection,
 
-   dataSource
 
- ) {
 
-   const resetClock = this.clockTrackedDataSource === dataSource;
 
-   const id = dataSource.entities.id;
 
-   this._dataSourceChangedListeners[id]();
 
-   this._dataSourceChangedListeners[id] = undefined;
 
-   if (resetClock) {
 
-     const numDataSources = dataSourceCollection.length;
 
-     if (this._automaticallyTrackDataSourceClocks && numDataSources > 0) {
 
-       this.clockTrackedDataSource = dataSourceCollection.get(
 
-         numDataSources - 1
 
-       );
 
-     } else {
 
-       this.clockTrackedDataSource = undefined;
 
-     }
 
-   }
 
- };
 
- /**
 
-  * Asynchronously sets the camera to view the provided entity, entities, or data source.
 
-  * If the data source is still in the process of loading or the visualization is otherwise still loading,
 
-  * this method waits for the data to be ready before performing the zoom.
 
-  *
 
-  * <p>The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere.
 
-  * The heading and the pitch angles are defined in the local east-north-up reference frame.
 
-  * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch
 
-  * angles are above the plane. Negative pitch angles are below the plane. The range is the distance from the center. If the range is
 
-  * zero, a range will be computed such that the whole bounding sphere is visible.</p>
 
-  *
 
-  * <p>In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the
 
-  * target will be the range. The heading will be determined from the offset. If the heading cannot be
 
-  * determined from the offset, the heading will be north.</p>
 
-  *
 
-  * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types.
 
-  * @param {HeadingPitchRange} [offset] The offset from the center of the entity in the local east-north-up reference frame.
 
-  * @returns {Promise.<Boolean>} A Promise that resolves to true if the zoom was successful or false if the target is not currently visualized in the scene or the zoom was cancelled.
 
-  */
 
- Viewer.prototype.zoomTo = function (target, offset) {
 
-   const options = {
 
-     offset: offset,
 
-   };
 
-   return zoomToOrFly(this, target, options, false);
 
- };
 
- /**
 
-  * Flies the camera to the provided entity, entities, or data source.
 
-  * If the data source is still in the process of loading or the visualization is otherwise still loading,
 
-  * this method waits for the data to be ready before performing the flight.
 
-  *
 
-  * <p>The offset is heading/pitch/range in the local east-north-up reference frame centered at the center of the bounding sphere.
 
-  * The heading and the pitch angles are defined in the local east-north-up reference frame.
 
-  * The heading is the angle from y axis and increasing towards the x axis. Pitch is the rotation from the xy-plane. Positive pitch
 
-  * angles are above the plane. Negative pitch angles are below the plane. The range is the distance from the center. If the range is
 
-  * zero, a range will be computed such that the whole bounding sphere is visible.</p>
 
-  *
 
-  * <p>In 2D, there must be a top down view. The camera will be placed above the target looking down. The height above the
 
-  * target will be the range. The heading will be determined from the offset. If the heading cannot be
 
-  * determined from the offset, the heading will be north.</p>
 
-  *
 
-  * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types.
 
-  * @param {Object} [options] Object with the following properties:
 
-  * @param {Number} [options.duration=3.0] The duration of the flight in seconds.
 
-  * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight.
 
-  * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target.
 
-  * @returns {Promise.<Boolean>} A Promise that resolves to true if the flight was successful or false if the target is not currently visualized in the scene or the flight was cancelled. //TODO: Cleanup entity mentions
 
-  */
 
- Viewer.prototype.flyTo = function (target, options) {
 
-   return zoomToOrFly(this, target, options, true);
 
- };
 
- function zoomToOrFly(that, zoomTarget, options, isFlight) {
 
-   //>>includeStart('debug', pragmas.debug);
 
-   if (!defined(zoomTarget)) {
 
-     throw new DeveloperError("zoomTarget is required.");
 
-   }
 
-   //>>includeEnd('debug');
 
-   cancelZoom(that);
 
-   //We can't actually perform the zoom until all visualization is ready and
 
-   //bounding spheres have been computed.  Therefore we create and return
 
-   //a deferred which will be resolved as part of the post-render step in the
 
-   //frame that actually performs the zoom
 
-   const zoomPromise = defer();
 
-   that._zoomPromise = zoomPromise;
 
-   that._zoomIsFlight = isFlight;
 
-   that._zoomOptions = options;
 
-   Promise.resolve(zoomTarget).then(function (zoomTarget) {
 
-     //Only perform the zoom if it wasn't cancelled before the promise resolved.
 
-     if (that._zoomPromise !== zoomPromise) {
 
-       return;
 
-     }
 
-     //If the zoom target is a rectangular imagery in an ImageLayer
 
-     if (zoomTarget instanceof ImageryLayer) {
 
-       zoomTarget
 
-         .getViewableRectangle()
 
-         .then(function (rectangle) {
 
-           return computeFlyToLocationForRectangle(rectangle, that.scene);
 
-         })
 
-         .then(function (position) {
 
-           //Only perform the zoom if it wasn't cancelled before the promise was resolved
 
-           if (that._zoomPromise === zoomPromise) {
 
-             that._zoomTarget = position;
 
-           }
 
-         });
 
-       return;
 
-     }
 
-     //If the zoom target is a Cesium3DTileset
 
-     if (zoomTarget instanceof Cesium3DTileset) {
 
-       that._zoomTarget = zoomTarget;
 
-       return;
 
-     }
 
-     //If the zoom target is a TimeDynamicPointCloud
 
-     if (zoomTarget instanceof TimeDynamicPointCloud) {
 
-       that._zoomTarget = zoomTarget;
 
-       return;
 
-     }
 
-     //If the zoom target is a data source, and it's in the middle of loading, wait for it to finish loading.
 
-     if (zoomTarget.isLoading && defined(zoomTarget.loadingEvent)) {
 
-       const removeEvent = zoomTarget.loadingEvent.addEventListener(function () {
 
-         removeEvent();
 
-         //Only perform the zoom if it wasn't cancelled before the data source finished.
 
-         if (that._zoomPromise === zoomPromise) {
 
-           that._zoomTarget = zoomTarget.entities.values.slice(0);
 
-         }
 
-       });
 
-       return;
 
-     }
 
-     //Zoom target is already an array, just copy it and return.
 
-     if (Array.isArray(zoomTarget)) {
 
-       that._zoomTarget = zoomTarget.slice(0);
 
-       return;
 
-     }
 
-     //If zoomTarget is an EntityCollection, this will retrieve the array
 
-     zoomTarget = defaultValue(zoomTarget.values, zoomTarget);
 
-     //If zoomTarget is a DataSource, this will retrieve the array.
 
-     if (defined(zoomTarget.entities)) {
 
-       zoomTarget = zoomTarget.entities.values;
 
-     }
 
-     //Zoom target is already an array, just copy it and return.
 
-     if (Array.isArray(zoomTarget)) {
 
-       that._zoomTarget = zoomTarget.slice(0);
 
-     } else {
 
-       //Single entity
 
-       that._zoomTarget = [zoomTarget];
 
-     }
 
-   });
 
-   that.scene.requestRender();
 
-   return zoomPromise.promise;
 
- }
 
- function clearZoom(viewer) {
 
-   viewer._zoomPromise = undefined;
 
-   viewer._zoomTarget = undefined;
 
-   viewer._zoomOptions = undefined;
 
- }
 
- function cancelZoom(viewer) {
 
-   const zoomPromise = viewer._zoomPromise;
 
-   if (defined(zoomPromise)) {
 
-     clearZoom(viewer);
 
-     zoomPromise.resolve(false);
 
-   }
 
- }
 
- /**
 
-  * @private
 
-  */
 
- Viewer.prototype._postRender = function () {
 
-   updateZoomTarget(this);
 
-   updateTrackedEntity(this);
 
- };
 
- function updateZoomTarget(viewer) {
 
-   const target = viewer._zoomTarget;
 
-   if (!defined(target) || viewer.scene.mode === SceneMode.MORPHING) {
 
-     return;
 
-   }
 
-   const scene = viewer.scene;
 
-   const camera = scene.camera;
 
-   const zoomPromise = viewer._zoomPromise;
 
-   const zoomOptions = defaultValue(viewer._zoomOptions, {});
 
-   let options;
 
-   // If zoomTarget was Cesium3DTileset
 
-   if (target instanceof Cesium3DTileset) {
 
-     return target.readyPromise.then(function () {
 
-       const boundingSphere = target.boundingSphere;
 
-       // If offset was originally undefined then give it base value instead of empty object
 
-       if (!defined(zoomOptions.offset)) {
 
-         zoomOptions.offset = new HeadingPitchRange(
 
-           0.0,
 
-           -0.5,
 
-           boundingSphere.radius
 
-         );
 
-       }
 
-       options = {
 
-         offset: zoomOptions.offset,
 
-         duration: zoomOptions.duration,
 
-         maximumHeight: zoomOptions.maximumHeight,
 
-         complete: function () {
 
-           zoomPromise.resolve(true);
 
-         },
 
-         cancel: function () {
 
-           zoomPromise.resolve(false);
 
-         },
 
-       };
 
-       if (viewer._zoomIsFlight) {
 
-         camera.flyToBoundingSphere(target.boundingSphere, options);
 
-       } else {
 
-         camera.viewBoundingSphere(boundingSphere, zoomOptions.offset);
 
-         camera.lookAtTransform(Matrix4.IDENTITY);
 
-         // Finish the promise
 
-         zoomPromise.resolve(true);
 
-       }
 
-       clearZoom(viewer);
 
-     });
 
-   }
 
-   // If zoomTarget was TimeDynamicPointCloud
 
-   if (target instanceof TimeDynamicPointCloud) {
 
-     return target.readyPromise.then(function () {
 
-       const boundingSphere = target.boundingSphere;
 
-       // If offset was originally undefined then give it base value instead of empty object
 
-       if (!defined(zoomOptions.offset)) {
 
-         zoomOptions.offset = new HeadingPitchRange(
 
-           0.0,
 
-           -0.5,
 
-           boundingSphere.radius
 
-         );
 
-       }
 
-       options = {
 
-         offset: zoomOptions.offset,
 
-         duration: zoomOptions.duration,
 
-         maximumHeight: zoomOptions.maximumHeight,
 
-         complete: function () {
 
-           zoomPromise.resolve(true);
 
-         },
 
-         cancel: function () {
 
-           zoomPromise.resolve(false);
 
-         },
 
-       };
 
-       if (viewer._zoomIsFlight) {
 
-         camera.flyToBoundingSphere(boundingSphere, options);
 
-       } else {
 
-         camera.viewBoundingSphere(boundingSphere, zoomOptions.offset);
 
-         camera.lookAtTransform(Matrix4.IDENTITY);
 
-         // Finish the promise
 
-         zoomPromise.resolve(true);
 
-       }
 
-       clearZoom(viewer);
 
-     });
 
-   }
 
-   // If zoomTarget was an ImageryLayer
 
-   if (target instanceof Cartographic) {
 
-     options = {
 
-       destination: scene.mapProjection.ellipsoid.cartographicToCartesian(
 
-         target
 
-       ),
 
-       duration: zoomOptions.duration,
 
-       maximumHeight: zoomOptions.maximumHeight,
 
-       complete: function () {
 
-         zoomPromise.resolve(true);
 
-       },
 
-       cancel: function () {
 
-         zoomPromise.resolve(false);
 
-       },
 
-     };
 
-     if (viewer._zoomIsFlight) {
 
-       camera.flyTo(options);
 
-     } else {
 
-       camera.setView(options);
 
-       zoomPromise.resolve(true);
 
-     }
 
-     clearZoom(viewer);
 
-     return;
 
-   }
 
-   const entities = target;
 
-   const boundingSpheres = [];
 
-   for (let i = 0, len = entities.length; i < len; i++) {
 
-     const state = viewer._dataSourceDisplay.getBoundingSphere(
 
-       entities[i],
 
-       false,
 
-       boundingSphereScratch
 
-     );
 
-     if (state === BoundingSphereState.PENDING) {
 
-       return;
 
-     } else if (state !== BoundingSphereState.FAILED) {
 
-       boundingSpheres.push(BoundingSphere.clone(boundingSphereScratch));
 
-     }
 
-   }
 
-   if (boundingSpheres.length === 0) {
 
-     cancelZoom(viewer);
 
-     return;
 
-   }
 
-   //Stop tracking the current entity.
 
-   viewer.trackedEntity = undefined;
 
-   const boundingSphere = BoundingSphere.fromBoundingSpheres(boundingSpheres);
 
-   if (!viewer._zoomIsFlight) {
 
-     camera.viewBoundingSphere(boundingSphere, zoomOptions.offset);
 
-     camera.lookAtTransform(Matrix4.IDENTITY);
 
-     clearZoom(viewer);
 
-     zoomPromise.resolve(true);
 
-   } else {
 
-     clearZoom(viewer);
 
-     camera.flyToBoundingSphere(boundingSphere, {
 
-       duration: zoomOptions.duration,
 
-       maximumHeight: zoomOptions.maximumHeight,
 
-       complete: function () {
 
-         zoomPromise.resolve(true);
 
-       },
 
-       cancel: function () {
 
-         zoomPromise.resolve(false);
 
-       },
 
-       offset: zoomOptions.offset,
 
-     });
 
-   }
 
- }
 
- function updateTrackedEntity(viewer) {
 
-   if (!viewer._needTrackedEntityUpdate) {
 
-     return;
 
-   }
 
-   const trackedEntity = viewer._trackedEntity;
 
-   const currentTime = viewer.clock.currentTime;
 
-   //Verify we have a current position at this time. This is only triggered if a position
 
-   //has become undefined after trackedEntity is set but before the boundingSphere has been
 
-   //computed. In this case, we will track the entity once it comes back into existence.
 
-   const currentPosition = Property.getValueOrUndefined(
 
-     trackedEntity.position,
 
-     currentTime
 
-   );
 
-   if (!defined(currentPosition)) {
 
-     return;
 
-   }
 
-   const scene = viewer.scene;
 
-   const state = viewer._dataSourceDisplay.getBoundingSphere(
 
-     trackedEntity,
 
-     false,
 
-     boundingSphereScratch
 
-   );
 
-   if (state === BoundingSphereState.PENDING) {
 
-     return;
 
-   }
 
-   const sceneMode = scene.mode;
 
-   if (
 
-     sceneMode === SceneMode.COLUMBUS_VIEW ||
 
-     sceneMode === SceneMode.SCENE2D
 
-   ) {
 
-     scene.screenSpaceCameraController.enableTranslate = false;
 
-   }
 
-   if (
 
-     sceneMode === SceneMode.COLUMBUS_VIEW ||
 
-     sceneMode === SceneMode.SCENE3D
 
-   ) {
 
-     scene.screenSpaceCameraController.enableTilt = false;
 
-   }
 
-   const bs =
 
-     state !== BoundingSphereState.FAILED ? boundingSphereScratch : undefined;
 
-   viewer._entityView = new EntityView(
 
-     trackedEntity,
 
-     scene,
 
-     scene.mapProjection.ellipsoid
 
-   );
 
-   viewer._entityView.update(currentTime, bs);
 
-   viewer._needTrackedEntityUpdate = false;
 
- }
 
- /**
 
-  * A function that augments a Viewer instance with additional functionality.
 
-  * @callback Viewer.ViewerMixin
 
-  * @param {Viewer} viewer The viewer instance.
 
-  * @param {Object} options Options object to be passed to the mixin function.
 
-  *
 
-  * @see Viewer#extend
 
-  */
 
- export default Viewer;
 
 
  |