@itwin/core-frontend
Version:
iTwin.js frontend components
609 lines • 30.5 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module IModelApp
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IModelApp = exports.ITWINJS_CORE_VERSION = void 0;
// @ts-expect-error package.json will resolve from the lib/{cjs,esm} dir without copying it into the build output we deliver
// eslint-disable-next-line @itwin/import-within-package
const package_json_1 = __importDefault(require("../../package.json"));
/** @public */
exports.ITWINJS_CORE_VERSION = package_json_1.default.version;
const COPYRIGHT_NOTICE = `Copyright © 2017-${new Date().getFullYear()} <a href="https://www.bentley.com" target="_blank" rel="noopener noreferrer">Bentley Systems, Inc.</a>`;
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const core_i18n_1 = require("@itwin/core-i18n");
const webgl_compatibility_1 = require("@itwin/webgl-compatibility");
const AccuDraw_1 = require("./AccuDraw");
const AccuSnap_1 = require("./AccuSnap");
const auxCoordState = __importStar(require("./AuxCoordSys"));
const categorySelectorState = __importStar(require("./CategorySelectorState"));
const ExtensionAdmin_1 = require("./extension/ExtensionAdmin");
const displayStyleState = __importStar(require("./DisplayStyleState"));
const drawingViewState = __importStar(require("./DrawingViewState"));
const ElementLocateManager_1 = require("./ElementLocateManager");
const EntityState_1 = require("./EntityState");
const FrontendLoggerCategory_1 = require("./common/FrontendLoggerCategory");
const modelselector = __importStar(require("./ModelSelectorState"));
const modelState = __importStar(require("./ModelState"));
const NotificationManager_1 = require("./NotificationManager");
const QuantityFormatter_1 = require("./quantity-formatting/QuantityFormatter");
const RenderSystem_1 = require("./render/RenderSystem");
const System_1 = require("./internal/render/webgl/System");
const sheetState = __importStar(require("./SheetViewState"));
const spatialViewState = __importStar(require("./SpatialViewState"));
const TentativePoint_1 = require("./TentativePoint");
const RealityDataSource_1 = require("./RealityDataSource");
const internal_1 = require("./tile/internal");
const accudrawTool = __importStar(require("./tools/AccuDrawTool"));
const clipViewTool = __importStar(require("./tools/ClipViewTool"));
const idleTool = __importStar(require("./tools/IdleTool"));
const measureTool = __importStar(require("./tools/MeasureTool"));
const selectTool = __importStar(require("./tools/SelectTool"));
const Tool_1 = require("./tools/Tool");
const ToolAdmin_1 = require("./tools/ToolAdmin");
const viewTool = __importStar(require("./tools/ViewTool"));
const ViewManager_1 = require("./ViewManager");
const viewState = __importStar(require("./ViewState"));
require("./IModeljs-css");
/**
* Global singleton that connects the user interface with the iTwin.js services. There can be only one IModelApp active in a session. All
* members of IModelApp are static, and it serves as a singleton object for gaining access to session information.
*
* Before any interactive operations may be performed by the `@itwin/core-frontend package`, [[IModelApp.startup]] must be called and awaited.
* Applications may customize the frontend behavior of iTwin.js by supplying options to [[IModelApp.startup]].
*
* @public
*/
class IModelApp {
static _initialized = false;
static _accuDraw;
static _accuSnap;
static _applicationId;
static _applicationVersion;
static _localization;
static _locateManager;
static _notifications;
static _quantityFormatter;
static _renderSystem;
static _userPreferences;
static _tentativePoint;
static _tileAdmin;
static _toolAdmin;
static _viewManager;
static _uiAdmin;
static _noRender;
static _wantEventLoop = false;
static _animationRequested = false;
static _animationInterval = core_bentley_1.BeDuration.fromSeconds(1);
static _animationIntervalId;
static _securityOptions;
static _mapLayerFormatRegistry;
static _terrainProviderRegistry;
static _realityDataSourceProviders;
static _hubAccess;
static _realityDataAccess;
static _publicPath;
static _formatsProviderManager;
// No instances of IModelApp may be created. All members are static and must be on the singleton object IModelApp.
constructor() { }
/** Event raised just before the frontend IModelApp is to be [[shutdown]]. */
static onBeforeShutdown = new core_bentley_1.BeEvent();
/** Event raised after IModelApp [[startup]] completes. */
static onAfterStartup = new core_bentley_1.BeEvent();
/** The AuthorizationClient used to obtain [AccessToken]($bentley)s. */
static authorizationClient;
/** The [[ToolRegistry]] for this session. */
static tools = new Tool_1.ToolRegistry();
/** A uniqueId for this session */
static sessionId;
/** The [[MapLayerFormatRegistry]] for this session. */
static get mapLayerFormatRegistry() { return this._mapLayerFormatRegistry; }
/** The [[TerrainProviderRegistry]] for this session. */
static get terrainProviderRegistry() { return this._terrainProviderRegistry; }
/** The [[RealityDataSourceProviderRegistry]] for this session.
* @beta
*/
static get realityDataSourceProviders() { return this._realityDataSourceProviders; }
/** The [[RenderSystem]] for this session. */
static get renderSystem() { return this._renderSystem; }
/** The [[ViewManager]] for this session. */
static get viewManager() { return this._viewManager; }
/** The [[NotificationManager]] for this session. */
static get notifications() { return this._notifications; }
/** The [[TileAdmin]] for this session. */
static get tileAdmin() { return this._tileAdmin; }
/** The [[QuantityFormatter]] for this session. */
static get quantityFormatter() { return this._quantityFormatter; }
/** The [[ToolAdmin]] for this session. */
static get toolAdmin() { return this._toolAdmin; }
/** The [[AccuDraw]] for this session. */
static get accuDraw() { return this._accuDraw; }
/** The [[AccuSnap]] for this session. */
static get accuSnap() { return this._accuSnap; }
static get locateManager() { return this._locateManager; }
/** The [[TentativePoint]] for this session]]. */
static get tentativePoint() { return this._tentativePoint; }
/** The [[Localization]] for this session. */
static get localization() { return this._localization; }
/** The [[UserPreferencesAccess]] for this session.
* @beta
*/
static get userPreferences() { return this._userPreferences; }
/** The Id of this application. Applications must set this to the Global Product Registry ID (GPRID) for usage logging. */
static get applicationId() { return this._applicationId; }
/** The version of this application. Must be set for usage logging. */
static get applicationVersion() { return this._applicationVersion; }
/** True after [[startup]] has been called, until [[shutdown]] is called. */
static get initialized() { return this._initialized; }
/** Provides access to IModelHub services. */
static get hubAccess() { return this._hubAccess; }
/** Provides access to the RealityData service implementation for this IModelApp
* @beta
*/
static get realityDataAccess() { return this._realityDataAccess; }
/** Whether the [renderSystem[]] has been successfully initialized.
* This will always be `false` before calling [[startup]] and after calling [[shutdown]].
* In rare circumstances (e.g., while executing in a headless test environment) it may remain `false` due to a failure to
* obtain a [WebGL rendering context](https://www.google.com/search?channel=fs&client=ubuntu-sn&q=mdn+webglrenderingcontext).
* As long as you have called [[startup]], you can generally assume it to be `true`.
*/
static get hasRenderSystem() {
return this._renderSystem !== undefined && this._renderSystem.isValid;
}
/** The [[UiAdmin]] for this session. */
static get uiAdmin() { return this._uiAdmin; }
/** The requested security options for the frontend. */
static get securityOptions() { return this._securityOptions; }
/** If present, overrides where public assets are fetched. The default is to fetch assets relative to the current URL.
* The path should always end with a trailing `/`.
*/
static get publicPath() { return this._publicPath; }
/** The [[FormatsProvider]] for this session.
* @param provider The provider to use for formatting quantities.
* @beta
*/
static get formatsProvider() { return this._formatsProviderManager; }
static set formatsProvider(provider) {
this._formatsProviderManager.formatsProvider = provider;
}
/** @alpha */
static extensionAdmin = this._createExtensionAdmin();
/** Map of classFullName to EntityState class */
static _entityClasses = new Map();
/** Register all of the subclasses of EntityState from a module.
* @internal
*/
static registerModuleEntities(moduleObj) {
for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in
const thisEntityState = moduleObj[thisMember];
if (thisEntityState.prototype instanceof EntityState_1.EntityState) {
this.registerEntityState(thisEntityState.classFullName, thisEntityState);
}
}
}
/** Register an EntityState class by its classFullName
* @internal
*/
static registerEntityState(classFullName, classType) {
const lowerName = classFullName.toLowerCase();
if (this._entityClasses.has(lowerName)) {
const errMsg = `Class ${classFullName} is already registered. Make sure static schemaName and className members are correct on class ${classType.name}`;
core_bentley_1.Logger.logError(FrontendLoggerCategory_1.FrontendLoggerCategory.IModelConnection, errMsg);
throw new Error(errMsg);
}
this._entityClasses.set(lowerName, classType);
}
/** @internal */
static lookupEntityClass(classFullName) { return this._entityClasses.get(classFullName.toLowerCase()); }
/**
* Obtain WebGL rendering compatibility information for the client system. This information describes whether the client meets the
* minimum rendering capabilities. It also describes whether the system lacks any optional capabilities that could improve quality
* and/or performance.
* @note As of 4.x, iTwin.js requires WebGL 2. If the client does not support WebGL 2, the `status` field of the returned compatibility info will be [WebGLRenderCompatibilityStatus.CannotCreateContext]($webgl-compatibility).
*/
static queryRenderCompatibility() {
return (0, webgl_compatibility_1.queryRenderCompatibility)(true, (canvas, useWebGL2, inputContextAttributes) => System_1.System.createContext(canvas, useWebGL2, inputContextAttributes));
}
/**
* This method must be called before any other `@itwin/core-frontend` methods are used.
* Somewhere in your startup code, call [[IModelApp.startup]]. E.g.:
* ``` ts
* await IModelApp.startup( {applicationId: myAppId} );
* ```
* @param opts The options for configuring IModelApp
*/
static async startup(opts) {
if (this._initialized)
return; // we're already initialized, do nothing.
this._initialized = true;
opts = opts ?? {};
this._securityOptions = opts.security ?? {};
if (process.env.NODE_ENV === "development") {
// Make IModelApp globally accessible for debugging purposes. We'll remove it on shutdown.
window.iModelAppForDebugger = this;
}
this.sessionId = opts.sessionId ?? core_bentley_1.Guid.createValue();
this._applicationId = opts.applicationId ?? "2686"; // Default to product id of iTwin.js
this._applicationVersion = opts.applicationVersion ?? "1.0.0";
this.authorizationClient = opts.authorizationClient;
this._hubAccess = opts.hubAccess;
this._noRender = opts.noRender ?? false;
this._setupRpcRequestContext();
this._localization = opts.localization ?? new core_i18n_1.ITwinLocalization();
const toolsNs = "CoreTools";
await this.localization.initialize(["iModelJs", toolsNs]);
[
selectTool,
idleTool,
viewTool,
clipViewTool,
measureTool,
accudrawTool,
].forEach((tool) => this.tools.registerModule(tool, toolsNs));
this.registerEntityState(EntityState_1.EntityState.classFullName, EntityState_1.EntityState);
[
modelState,
sheetState,
viewState,
drawingViewState,
spatialViewState,
displayStyleState,
modelselector,
categorySelectorState,
auxCoordState,
].forEach((module) => this.registerModuleEntities(module));
this._renderSystem = (opts.renderSys instanceof RenderSystem_1.RenderSystem) ? opts.renderSys : this.createRenderSys(opts.renderSys);
if (opts.userPreferences)
this._userPreferences = opts.userPreferences;
this._viewManager = opts.viewManager ?? new ViewManager_1.ViewManager();
this._tileAdmin = await internal_1.TileAdmin.create(opts.tileAdmin);
this._notifications = opts.notifications ?? new NotificationManager_1.NotificationManager();
this._toolAdmin = opts.toolAdmin ?? new ToolAdmin_1.ToolAdmin();
this._accuDraw = opts.accuDraw ?? new AccuDraw_1.AccuDraw();
this._accuSnap = opts.accuSnap ?? new AccuSnap_1.AccuSnap();
this._locateManager = opts.locateManager ?? new ElementLocateManager_1.ElementLocateManager();
this._tentativePoint = opts.tentativePoint ?? new TentativePoint_1.TentativePoint();
this._quantityFormatter = opts.quantityFormatter ?? new QuantityFormatter_1.QuantityFormatter();
this._uiAdmin = opts.uiAdmin ?? new appui_abstract_1.UiAdmin();
this._mapLayerFormatRegistry = new internal_1.MapLayerFormatRegistry(opts.mapLayerOptions);
this._terrainProviderRegistry = new internal_1.TerrainProviderRegistry();
this._realityDataSourceProviders = new RealityDataSource_1.RealityDataSourceProviderRegistry();
this._realityDataAccess = opts.realityDataAccess;
this._formatsProviderManager = new QuantityFormatter_1.FormatsProviderManager(opts.formatsProvider ?? new QuantityFormatter_1.QuantityTypeFormatsProvider());
this._publicPath = opts.publicPath ?? "";
[
this.renderSystem,
this.viewManager,
this.toolAdmin,
this.accuDraw,
this.accuSnap,
this.locateManager,
this.tentativePoint,
this.uiAdmin,
].forEach((sys) => sys.onInitialized());
await this.quantityFormatter.onInitialized();
this.onAfterStartup.raiseEvent();
}
/** Must be called before the application exits to release any held resources. */
static async shutdown() {
if (!this._initialized)
return;
// notify listeners that this IModelApp is about to be shut down.
this.onBeforeShutdown.raiseEvent();
this.onBeforeShutdown.clear();
if (process.env.NODE_ENV === "development") {
window.iModelAppForDebugger = undefined;
}
this._wantEventLoop = false;
window.removeEventListener("resize", () => IModelApp.requestNextAnimation());
this.clearIntervalAnimation();
[this.toolAdmin, this.viewManager, this.tileAdmin].forEach((sys) => sys.onShutDown());
this.tools.shutdown();
this._renderSystem = (0, core_bentley_1.dispose)(this._renderSystem);
this._entityClasses.clear();
this.authorizationClient = undefined;
this._initialized = false;
this.quantityFormatter[Symbol.dispose]();
this.resetFormatsProvider();
this.onAfterStartup.clear();
}
/** Controls how frequently the application polls for changes that may require a new animation frame to be requested.
* Such changes include resizing a Viewport or changing the device pixel ratio by zooming in or out in the browser.
* The default interval is 1 second. It may be desirable to override the default for specific apps and/or devices.
* - Increasing the interval can conserve battery life on battery-powered devices at the expense of slower response to resize events.
* - An application that only displays a single Viewport whose dimensions only change when the dimensions of the application window change, and which does not support changing application zoom level, could disable the interval altogether.
* @param interval The interval at which to poll for changes. If undefined (or negative), the application will never poll. If zero, the application will poll as frequently as possible.
* @beta
*/
static get animationInterval() { return IModelApp._animationInterval; }
static set animationInterval(interval) {
if (undefined !== interval && interval.isTowardsPast)
interval = undefined;
if (interval !== IModelApp._animationInterval) {
IModelApp._animationInterval = interval;
if (IModelApp._wantEventLoop)
IModelApp.requestIntervalAnimation();
}
}
/** Request that the event loop execute on the next [animation frame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
* There is generally no reason for applications to invoke this method directly.
*/
static requestNextAnimation() {
// Only want to call requestAnimationFrame if it is defined. Need to check whether current iModelApp is a NoRenderApp.
if (IModelApp._noRender)
return;
if (!IModelApp._animationRequested) {
IModelApp._animationRequested = true;
requestAnimationFrame(() => IModelApp.eventLoop());
}
}
/** @internal */
static clearIntervalAnimation() {
if (undefined !== IModelApp._animationIntervalId) {
window.clearInterval(IModelApp._animationIntervalId);
IModelApp._animationIntervalId = undefined;
}
}
/** @internal */
static requestIntervalAnimation() {
IModelApp.clearIntervalAnimation();
if (undefined !== IModelApp.animationInterval)
IModelApp._animationIntervalId = window.setInterval(() => {
IModelApp.requestNextAnimation();
}, IModelApp.animationInterval.milliseconds);
}
/** @internal */
static startEventLoop() {
if (!IModelApp._wantEventLoop) {
IModelApp._wantEventLoop = true;
window.addEventListener("resize", () => IModelApp.requestNextAnimation());
IModelApp.requestIntervalAnimation();
IModelApp.requestNextAnimation();
}
}
/** Strictly for tests. @internal */
static stopEventLoop() {
this._wantEventLoop = false;
}
/** The main event processing loop for Tools and rendering. */
static eventLoop() {
IModelApp._animationRequested = false;
if (!IModelApp._wantEventLoop) // flag turned on at startup
return;
try {
IModelApp.toolAdmin.processEvent(); // eslint-disable-line @typescript-eslint/no-floating-promises
IModelApp.viewManager.renderLoop();
IModelApp.tileAdmin.process();
}
catch (exception) {
ToolAdmin_1.ToolAdmin.exceptionHandler(exception); // eslint-disable-line @typescript-eslint/no-floating-promises
IModelApp._wantEventLoop = false;
IModelApp._animationRequested = true; // unrecoverable after exception, don't request any further frames.
window.removeEventListener("resize", () => IModelApp.requestNextAnimation());
}
}
/** Get the user's access token for this IModelApp, or a blank string if none is available.
* @note Access tokens expire periodically and are automatically refreshed, if possible. Therefore tokens should not be saved, and the value
* returned by this method may change over time throughout the course of a session.
*/
static async getAccessToken() {
try {
return (await this.authorizationClient?.getAccessToken()) ?? "";
}
catch {
return "";
}
}
/** @internal */
static createRenderSys(opts) { return System_1.System.create(opts); }
static _setupRpcRequestContext() {
core_common_1.RpcConfiguration.requestContext.getId = (_request) => {
return core_bentley_1.Guid.createValue();
};
core_common_1.RpcConfiguration.requestContext.serialize = async (_request) => {
const id = _request.id;
const serialized = {
id,
applicationId: this.applicationId,
applicationVersion: this.applicationVersion,
sessionId: this.sessionId,
authorization: core_bentley_1.ProcessDetector.isMobileAppFrontend ? "" : await this.getAccessToken(),
};
const csrf = IModelApp.securityOptions.csrfProtection;
if (csrf && csrf.enabled) {
const cookieName = csrf.cookieName || "XSRF-TOKEN";
const cookieValue = document.cookie.split("; ").find((r) => r.startsWith(`${cookieName}=`));
if (cookieValue) {
const headerName = csrf.headerName || "X-XSRF-TOKEN";
const headerValue = cookieValue.split("=")[1];
serialized.csrfToken = { headerName, headerValue };
}
}
return serialized;
};
}
/** Shortcut for creating an HTMLElement with optional parent, className, id, innerHTML, innerText. */
static makeHTMLElement(type, opt) {
const el = document.createElement(type);
if (undefined !== opt) {
if (undefined !== opt.className)
el.className = opt.className;
if (undefined !== opt.id)
el.id = opt.id;
if (undefined !== opt.innerHTML)
el.innerHTML = opt.innerHTML;
if (undefined !== opt.innerText)
el.innerText = opt.innerText;
if (undefined !== opt.parent)
opt.parent.appendChild(el);
}
return el;
}
/** Shortcut for making a modal dialog on top of the root of the application. The returned HTMLDivElement will be placed topmost, all other application
* windows will be covered with a semi-transparent background that intercepts all key/mouse/touch events until the modal is dismissed.
* @param options The options that describe how the modal should work.
*/
static makeModalDiv(options) {
const root = options.rootDiv ? options.rootDiv : document.body;
// create the overlay div to "black out" the application to indicate everything is inactive until the modal has been dismissed.
const overlay = IModelApp.makeHTMLElement("div", { parent: root, className: "imodeljs-modal-overlay" });
overlay.tabIndex = -1; // so we can catch keystroke events
// function to remove modal dialog
const stop = (ev) => {
root.removeChild(overlay);
ev.stopPropagation();
};
if (options.autoClose) {
overlay.onclick = overlay.oncontextmenu = stop;
overlay.onkeydown = overlay.onkeyup = (ev) => {
switch (ev.key) {
case "Enter":
case "Escape":
stop(ev);
return;
}
ev.stopPropagation();
};
overlay.focus();
}
const modal = IModelApp.makeHTMLElement("div", { parent: overlay, className: "imodeljs-modal" });
if (undefined !== options.width) {
modal.style.width = `${options.width}px`;
// allow the dialog to be smaller than the width
modal.style.maxWidth = `min(100% - (2 * var(--width-border)), ${options.width}px)`;
}
if (options.closeBox) {
const close = IModelApp.makeHTMLElement("p", { parent: modal, className: "imodeljs-modal-close" });
close.innerText = "\u00d7"; // unicode "times" symbol
close.onclick = stop;
}
return { modal, stop };
}
/** Applications may implement this method to supply a Logo Card.
* @beta
*/
static applicationLogoCard;
/** Make a new Logo Card. Call this method from your implementation of [[IModelApp.applicationLogoCard]]
* @param opts Options for Logo Card
* @beta
*/
static makeLogoCard(opts) {
const card = IModelApp.makeHTMLElement("tr");
const iconCell = IModelApp.makeHTMLElement("td", { parent: card, className: "logo-card-logo" });
if (undefined !== opts.iconSrc) {
if (typeof opts.iconSrc === "string") {
const logo = IModelApp.makeHTMLElement("img");
logo.src = opts.iconSrc;
logo.width = opts.iconWidth ? opts.iconWidth : 64;
opts.iconSrc = logo;
}
iconCell.appendChild(opts.iconSrc);
}
const noticeCell = IModelApp.makeHTMLElement("td", { parent: card, className: "logo-card-message" });
if (undefined !== opts.heading) {
if (typeof opts.heading === "string")
IModelApp.makeHTMLElement("h2", { parent: noticeCell, innerHTML: opts.heading, className: "logo-card-header" });
else
noticeCell.appendChild(opts.heading);
}
if (undefined !== opts.notice) {
if (typeof opts.notice === "string")
IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: "logo-cards" });
else
noticeCell.appendChild(opts.notice);
}
return card;
}
/** Make the logo card for the library itself. This card gets placed at the top of the stack.
* @internal
*/
static makeIModelJsLogoCard() {
return this.makeLogoCard({
iconSrc: `${this.publicPath}images/about-imodeljs.svg`,
heading: `<span style="font-weight:normal">${this.localization.getLocalizedString("iModelJs:Notices.PoweredBy")}</span> iTwin.js`,
notice: `${exports.ITWINJS_CORE_VERSION}<br>${COPYRIGHT_NOTICE}`,
});
}
/** Format the tooltip strings returned by [[IModelConnection.getToolTipMessage]].
* @alpha
*/
static formatElementToolTip(msg) {
let out = "";
msg.forEach((line) => out += `${IModelApp.localization?.getLocalizedKeys(line)}<br>`);
const div = document.createElement("div");
div.innerHTML = out;
return div;
}
/** Localize an error status
* @param status one of the status values from [BentleyStatus]($core-bentley), [IModelStatus]($core-bentley) or [DbResult]($core-bentley)
* @returns a localized error message
* @beta
*/
static translateStatus(status) {
let key;
if (typeof status !== "number") {
key = { scope: "Errors", val: "IllegalValue" };
}
else {
key = { scope: "BentleyStatus", val: core_bentley_1.BentleyStatus[status] };
if (!key.val)
key = { scope: "IModelStatus", val: core_bentley_1.IModelStatus[status] };
if (!key.val)
key = { scope: "DbResult", val: core_bentley_1.DbResult[status] };
if (!key.val)
key = { scope: "Errors", val: "Status", status: status.toString() };
}
return this.localization.getLocalizedString(`iModelJs:${key.scope}.${key.val}`, key);
}
/**
* Resets the formatsProvider back to the default [[QuantityTypeFormatsProvider]].
* @beta
*/
static resetFormatsProvider() {
this.formatsProvider = new QuantityFormatter_1.QuantityTypeFormatsProvider();
}
/**
* Creates an instance of the ExtensionAdmin
* and registers an event to execute after startup is complete
* @returns an instance of ExtensionAdmin
*/
static _createExtensionAdmin() {
const extensionAdmin = new ExtensionAdmin_1.ExtensionAdmin();
IModelApp.onAfterStartup.addListener(extensionAdmin.onStartup);
return extensionAdmin;
}
}
exports.IModelApp = IModelApp;
//# sourceMappingURL=IModelApp.js.map