UNPKG

@tangential/core

Version:

Core types and support code for Tangential

1 lines 84.5 kB
{"version":3,"file":"tangential-core.mjs","sources":["../../../../projects/tangential/core/src/lib/data/selection-list.ts","../../../../projects/tangential/core/src/lib/lang/array-util.ts","../../../../projects/tangential/core/src/lib/lang/guard/guard.ts","../../../../projects/tangential/core/src/lib/lang/coded-error.ts","../../../../projects/tangential/core/src/lib/lang/obj-map-util.ts","../../../../projects/tangential/core/src/lib/util/core-util.ts","../../../../projects/tangential/core/src/lib/lang/json-util.ts","../../../../projects/tangential/core/src/lib/lang/reactive-util.ts","../../../../projects/tangential/core/src/lib/lang/string-util.ts","../../../../projects/tangential/core/src/lib/media-type/app-environment.ts","../../../../projects/tangential/core/src/lib/util/generate-push-id.ts","../../../../projects/tangential/core/src/lib/message-bus/message-bus.ts","../../../../projects/tangential/core/src/lib/message-bus/logging/log-message.ts","../../../../projects/tangential/core/src/lib/message-bus/logging/logger.ts","../../../../projects/tangential/core/src/lib/message-bus/logging/console-logger.ts","../../../../projects/tangential/core/src/lib/message-bus/logging/bus-logger.ts","../../../../projects/tangential/core/src/lib/message-bus/navigation/navigation-message.ts","../../../../projects/tangential/core/src/lib/message-bus/application/application-message.ts","../../../../projects/tangential/core/src/lib/routing/route-info.ts","../../../../projects/tangential/core/src/lib/routing/ng-route-util.ts","../../../../projects/tangential/core/src/lib/time/time-unit.ts","../../../../projects/tangential/core/src/lib/util/hacks.ts","../../../../projects/tangential/core/src/lib/util/localization-util.ts","../../../../projects/tangential/core/src/lib/util/name-generator.ts","../../../../projects/tangential/core/src/lib/util/ng-util.ts","../../../../projects/tangential/core/src/lib/util/transform-util.ts","../../../../projects/tangential/core/src/lib/view/page.ts","../../../../projects/tangential/core/src/public-api.ts","../../../../projects/tangential/core/src/tangential-core.ts"],"sourcesContent":["export class SelectionEntry<T> {\n\n constructor(public value: T, public selected: boolean = false, public disabled: boolean = false) {\n }\n}\n\nexport class SelectionList<T> {\n entries: SelectionEntry<T>[]\n\n constructor(initialValues: T[] = [], selectAll: boolean = false, public keyField: string = '$key') {\n this.entries = initialValues.map((v) => {\n return new SelectionEntry(v, selectAll)\n })\n }\n\n asIndexMap() {\n const indices: { [key: string]: number } = {}\n this.entries.forEach((entry, index) => {\n indices[(entry.value as any)[this.keyField]] = index\n })\n return indices\n }\n\n select(values: T[]) {\n const map = this.asIndexMap()\n values.forEach((value: T) => {\n const index: number = (map as any)[(value as any)[this.keyField]]\n if (index || index === 0) {\n this.entries[index].selected = true\n }\n })\n }\n\n disable(values: T[]) {\n const map = this.asIndexMap()\n values.forEach((value: T) => {\n const index: number = (map as any)[(value as any)[this.keyField]]\n if (index || index === 0) {\n this.entries[index].disabled = true\n }\n })\n }\n}\n","export class ArrayUtils {\n\n static peek<T>(ary: T[]): T | undefined {\n let v: T | undefined = undefined\n if (ary && ary.length) {\n v = ary[ary.length - 1]\n }\n return v\n }\n}\n","export class Guard {\n static isString(value: any | string): value is string {\n return typeof value === 'string'\n }\n}\n","export class CodedError extends Error {\n\n constructor(message: string, public code: any) {\n super(message)\n }\n}\n","import {ObjMap} from './obj-map'\nexport class ObjMapUtil {\n\n static fromKeyedEntityArray<V>(values: V[], keyField: string = '$key'): ObjMap<V> {\n values = values || []\n const m: ObjMap<V> = {}\n for (let i = 0; i < values.length; i++) {\n (m as any)[(values[i] as any)[keyField]] = values[i]\n }\n return m\n }\n\n static toArray<V>(map: ObjMap<V>): V[] {\n return Object.keys(map).map((key) => {\n return map[key]\n })\n }\n\n static toKeyedEntityArray<V>(map: ObjMap<V>, keyField: string = '$key'): V[] {\n return Object.keys(map).map((key) => {\n const keyObj = {}; // semicolon actually required here.\n (keyObj as any)[keyField] = key\n return Object.assign({}, map[key], keyObj)\n })\n }\n\n static toTruthMap<V>(map: ObjMap<V>): ObjMap<boolean> {\n const result: ObjMap<boolean> = {}\n Object.keys(map).forEach((key) => {\n result[key] = true\n })\n return result\n }\n\n static addAll<V>(map: ObjMap<V>, mapB: ObjMap<V>, noOverwrite: boolean = false): ObjMap<V> {\n map = map || {}\n mapB = mapB || {}\n Object.keys(mapB).forEach((key: string) => {\n if (noOverwrite && map[key] !== undefined) {\n throw new Error(`Key already exists on map, cannot replace: ${key}.`)\n }\n map[key] = mapB[key]\n })\n return map\n }\n\n static removeAll<V>(map: ObjMap<V>, mapB: ObjMap<V>) {\n Object.keys(mapB).forEach((key: string) => {\n if (map[key] !== undefined) {\n delete map[key]\n }\n })\n }\n\n /**\n * Remove the child fields from the provided map.\n * @param map\n * @param fields {string[]}\n * @returns {ObjMap<V>}\n */\n static deleteValueFields<V>(map: ObjMap<V>, fields: string[] = ['$key']): ObjMap<V> {\n map = map || {}\n fields.forEach((fieldKey) => {\n Object.keys(map).forEach((key) => {\n delete (map as any)[key][fieldKey]\n })\n })\n return map\n }\n}\n","import {ObjMap} from '../lang/obj-map'\n\n\nexport interface MapEntry<T> { key: string, value: T\n}\n\nexport const ResolveVoid = undefined\n\nexport class ObjectUtil {\n\n\n /**\n * Null safe version of Object.keys.\n * @param map\n * @returns {string[]} The keys for the map, or an empty array if the argument provided is falsy.\n */\n static keys<T>(map: ObjMap<T>): string[] {\n return Object.keys(map || {})\n }\n\n /**\n * Provide a map of keys such that 'map[key]' provides a literal true value if the key is present, even if the value\n * on the source map is falsy.\n */\n static toTruthMap(ary: string[]): ObjMap<boolean> {\n const map = {}\n ary.forEach(value => (map as any)[value] = true)\n return map\n }\n\n /**\n * Expand the map into an array of key-value pairs.\n * @param {ObjMap<T extends object>} map\n * @returns MapEntry<T>\n */\n static entries<T>(map: ObjMap<T> | any): MapEntry<T>[] {\n const ret:MapEntry<T>[] = Object.keys(map || {}).map((key) => {\n return {key: key, value: map[key]}\n })\n return ret\n }\n\n /**\n * Provide the values of the map.\n * @param {ObjMap<T>} map\n * @returns MapEntry<T>\n */\n static values<T>(map: ObjMap<T> | any): T[] {\n return Object.keys(map || {}).map((key) => {\n return map[key]\n })\n }\n\n static isObject(value:any): boolean {\n return (typeof value === 'object' || value.constructor === Object)\n }\n\n static isFunction(value:any): boolean {\n return (typeof value === 'function' || value instanceof Function)\n }\n\n static isNullOrDefined(value:any): boolean {\n return value === null || value === undefined\n }\n\n static exists(value:any): boolean {\n return value !== null && value !== undefined\n }\n\n static assignDeep(target: any, ...sources: any[]): any {\n target = target || {}\n const L = sources.length\n for (let i = 0; i < L; i++) {\n const source = sources[i] || {}\n Object.keys(source).forEach(key => {\n const value = source[key]\n if (value && ObjectUtil.isObject(value)) {\n target[key] = ObjectUtil.assignDeep({}, target[key] || {}, value)\n } else {\n target[key] = value\n }\n })\n }\n return target\n }\n\n\n static removeNullish<T>(obj: T): T {\n const cleanObj: T = <T>{}\n Object.keys(obj as any).forEach((key) => {\n const v = (obj as any)[key]\n if (v !== null && v !== undefined) {\n (cleanObj as any)[key] = v\n }\n })\n return cleanObj\n }\n\n}\n\nexport const cleanFirebaseMap = function <T>(firebaseList: ObjMap<T>, deep?: boolean): ObjMap<T> {\n const result: ObjMap<T> = {}\n\n Object.keys(firebaseList).forEach((key: string) => {\n if (key[0] !== '$') {\n if (deep && firebaseList[key] instanceof Object) {\n result[key] = <any>cleanFirebaseMap(<any>firebaseList[key], true)\n } else {\n result[key] = firebaseList[key]\n }\n }\n })\n return result\n}\nexport const pathExists = (object: any, path: string): any => {\n const parts = path.split('\\.')\n let exists = true\n let obj = object\n for (let i = 0; i < parts.length; i++) {\n obj = obj[parts[i]]\n if (obj === undefined) {\n exists = false\n break\n }\n }\n return exists\n}\n\nexport const ensureExists = (object: any, path: string, value: any = true): any => {\n const parts = path.split('\\.')\n let obj = object\n for (let i = 0; i < parts.length - 1; i++) {\n const key = parts[i]\n if (obj[key] === undefined) {\n obj[key] = {}\n }\n obj = obj[key]\n }\n const lastKey = parts[parts.length - 1]\n if (obj[lastKey] === undefined) {\n obj[lastKey] = value\n }\n return obj[lastKey]\n}\n\nexport const removeIfExists = (object: any, path: string): boolean => {\n const parts = path.split('\\.')\n let obj = object\n let existed = true\n for (let i = 0; i < parts.length - 1; i++) {\n obj = obj[parts[i]]\n if (obj === undefined) {\n existed = false\n break\n }\n }\n if (existed) {\n const lastKey = parts[parts.length - 1]\n existed = obj[lastKey] !== undefined\n if (existed) {\n delete obj[lastKey]\n }\n }\n return existed\n}\n\nexport const safe = (fn: () => any) => {\n try {\n return fn()\n } catch (e) {\n return null\n }\n}\n\nexport const eachKey = <T extends {}>(objMap: T, fn: (arg?: T, key?: string) => any) => {\n Object.keys(objMap).forEach((key: string) => {\n fn((objMap as any)[key], key)\n })\n}\n\n\nexport interface Duo<X, Y> {\n x: X\n y: Y\n}\n","import {MapEntry, ObjectUtil} from '../util/core-util'\nimport {ObjMap} from './obj-map'\n\n\nexport interface ToJson<T> {\n toJson(withHiddenFields?: boolean): T\n}\n\n\nexport interface Jsonified<T, J extends ObjMap<any>> extends ToJson<J> {\n getModel(): J\n\n\n}\n\nexport class JsonUtil {\n\n static diff<T>(left: T, right: T): T {\n const diff = <T>{}\n let keys = ObjectUtil.keys(<any>left).concat(ObjectUtil.keys(<any>right))\n keys = ObjectUtil.keys(ObjectUtil.toTruthMap(keys))\n keys.forEach(key => {\n const leftVal = (left as any)[key]\n const rightVal = (right as any)[key]\n if (!JsonUtil.areEqual(leftVal, rightVal)) {\n (diff as any)[key] = true\n }\n })\n return diff\n }\n\n\n private static areEqual(left:any, right:any): boolean {\n let areEqual\n if (left === right) {\n areEqual = true\n } else if (!left || !right) {\n areEqual = false\n } else if (ObjectUtil.isObject(left)) {\n if (!ObjectUtil.isObject(right)) {\n areEqual = false\n } else {\n areEqual = ObjectUtil.keys(JsonUtil.diff(left, right)).length === 0\n }\n }\n return areEqual || false\n }\n\n static applyJsonToInstance<T, J extends ObjMap<any>>(instance: Jsonified<T, J>, json: J) {\n const model = instance.getModel()\n json = json || <any>{}\n ObjectUtil.keys(model).forEach((key) => {\n (instance as any)[key] = this.determineValue(json[key], model[key])\n })\n }\n\n private static determineValue<T, J extends ObjMap<any>>(jsonValue: any, defaultValue: any): any {\n let value = null\n if (ObjectUtil.isNullOrDefined(jsonValue)) {\n value = defaultValue\n } else if (ObjectUtil.isObject(jsonValue)) {\n value = ObjectUtil.assignDeep({}, defaultValue, jsonValue)\n } else {\n value = jsonValue\n }\n return value\n }\n\n static instanceToJson<T, J extends ObjMap<any>>(instance: Jsonified<T, J>, withHiddenFields?: boolean) {\n const model = instance.getModel()\n const json = <any>{}\n ObjectUtil.keys(model).forEach((key) => {\n if (withHiddenFields || JsonUtil.isLegalFirebaseKey(key)) {\n const value = (instance as any)[key]\n json[key] = value\n if (value) {\n if (ObjectUtil.isFunction(value['toJson'])) {\n json[key] = value.toJson(withHiddenFields)\n } else if (ObjectUtil.isObject(value)) {\n json[key] = JsonUtil.mapToJson(value, withHiddenFields || false)\n }\n }\n }\n })\n return json\n }\n\n\n static mapToJson<J extends object>(map: ObjMap<J>, withHiddenFields: boolean): ObjMap<J> {\n const json:any = {}\n // @ts-ignore Typescript is confused by the return type of ObjectUtil.entries.\n ObjectUtil.entries(map).forEach((entry: MapEntry<J>) => {\n let v: any = entry.value\n if (v && v['toJson'] && ObjectUtil.isFunction(v['toJson'])) {\n v = v.toJson(withHiddenFields)\n }\n json[entry.key] = v\n })\n return json\n }\n\n static keyedArrayToJsonMap<J extends object>(array: ToJson<J>[], withHiddenFields: boolean, keyField: string = '$key'): ObjMap<J> {\n const json:any = {}\n array.forEach(entry => {\n json[(entry as any)[keyField]] = entry.toJson(withHiddenFields)\n })\n return json\n }\n\n /**\n * @param obj\n * @returns {T}\n * @deprecated See FireBlanket.util.removeIllegalKey\n */\n static removeIllegalFirebaseKeys<T extends object>(obj: T): T {\n const cleanObj: T = <T>{}\n Object.keys(obj).forEach((key) => {\n const v = obj[key as keyof T]\n if (JsonUtil.isLegalFirebaseKey(v as string)) {\n cleanObj[key as keyof T] = v\n }\n })\n return cleanObj\n }\n\n /**\n * @param key\n * @returns {boolean}\n * @deprecated See FireBlanket.util.isLegalFirebaseKey\n */\n static isLegalFirebaseKey(key: string): boolean {\n return key !== null && key !== undefined && !key.startsWith('$')\n }\n\n\n}\n","import {Subscription} from 'rxjs'\nexport class ReactiveUtil {\n\n static unSub(subscription: Subscription) {\n if (subscription) {\n subscription.unsubscribe()\n }\n }\n\n}\n","export class StringUtil {\n\n static _baseTen = [true, true, true, true, true, true, true, true, true, true]\n\n static firstUniqueByCounterSuffix(value: string, values: string[], separatorChar: string = ' ') {\n let result = value\n const map: { [key: string]: boolean } = {}\n values.forEach(v => map[v] = true)\n let idx = 1\n while (map[result]) {\n result = value + separatorChar + idx++\n }\n return result\n }\n\n\n /**\n * Split a string that ends with a number into its corresponding parts. Useful for name collisions, e.g.\n * FooValue, FooValue-1, FooValue-2\n * @param value\n */\n static withoutNumericSuffix(value: string): { text: string, suffix?: number } {\n let idx = value.length\n const suffixChars = []\n for (idx; idx--; idx > 0) {\n if ((StringUtil._baseTen as any)[value.charAt(idx)] !== true) {\n break;\n }\n suffixChars.unshift(value.charAt(idx))\n }\n const suffixValue = suffixChars.length ? Number.parseInt(suffixChars.join('')) : undefined\n const text = value.substring(0, idx)\n return {text: text.trim(), suffix: suffixValue}\n }\n\n static incrementCounterSuffix(value: string) {\n let result = value\n let suffixValue = 1\n const suffixChars = []\n let idx = value.length\n\n for (idx; idx--; idx > 0) {\n if ((StringUtil._baseTen as any)[value.charAt(idx)] !== true) {\n break;\n }\n suffixChars.unshift(value.charAt(idx))\n }\n if (suffixChars.length) {\n try {\n suffixValue = Number.parseInt(suffixChars.join(''))\n result = value.substring(0, idx + 1)\n } catch (e) {\n suffixValue = 1;\n }\n }\n return result + (suffixValue + 1)\n\n\n }\n}\n","export class AppEnvironment {\n firebase: {\n privateKeyPath: string,\n databaseTemplatePath: string,\n databaseRulesPath: string,\n backupDirName: string,\n config: {\n apiKey: string\n authDomain: string\n databaseURL: string\n projectId: string\n storageBucket: string\n messagingSenderId: string\n }\n } = {} as any // Class is another \"we'd use an interface if we could, but compiler deletes interfaces\"\n googleAdWords?: {\n enabled: boolean\n campaignId: string\n adClient: string\n adSlot: string\n }\n googleAnalytics?: {\n enabled: boolean\n trackingId: string\n }\n name: 'dev' | 'test' | 'stage' | 'prod' = 'dev'\n production: boolean = false\n suppressAds: boolean = false\n}\n","/**\n * From https://gist.github.com/mikelehen/3596a30bd69384624c11, via Firebase blog at\n * https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html\n * With minor tweaks for use with TypeScript\n **/\n\n\n/**\n * Fancy ID generator that creates 20-character string identifiers with the following properties:\n *\n * 1. They're based on timestamp so that they sort *after* any existing ids.\n * 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.\n * 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).\n * 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the\n * latter ones will sort after the former ones. We do this by using the previous random bits\n * but \"incrementing\" them by 1 (only in the case of a timestamp collision).\n */\n\n// Modeled after base64 web-safe chars, but ordered by ASCII.\nconst PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';\n// Timestamp of last push, used to prevent local collisions if you push twice in one ms.\nlet lastPushTime: number = 0;\n\n// We generate 72-bits of randomness which get turned into 12 characters and appended to the\n// timestamp to prevent collisions with other clients. We store the last characters we\n// generated because in the event of a collision, we'll use those same characters except\n// \"incremented\" by one.\nconst lastRandChars: number[] = [];\n\nexport const generatePushID: () => string = function () {\n let i: number;\n let now = Date.now();\n const duplicateTime = (now === lastPushTime);\n lastPushTime = now;\n\n const timeStampChars = new Array(8);\n for (i = 7; i >= 0; i--) {\n timeStampChars[i] = PUSH_CHARS.charAt(now % 64);\n // NOTE: Can't use << here because javascript will convert to int and lose the upper bits.\n now = Math.floor(now / 64);\n }\n if (now !== 0) {\n throw new Error('We should have converted the entire timestamp.');\n }\n\n\n let id = timeStampChars.join('');\n\n if (!duplicateTime) {\n for (i = 0; i < 12; i++) {\n lastRandChars[i] = Math.floor(Math.random() * 64);\n }\n } else {\n // If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.\n for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {\n lastRandChars[i] = 0;\n }\n lastRandChars[i]++;\n }\n for (i = 0; i < 12; i++) {\n id += PUSH_CHARS.charAt(lastRandChars[i]);\n }\n if (id.length !== 20) {\n throw new Error('Length should be 20.');\n }\n\n return id;\n};\n","import {\n EventEmitter,\n Injectable\n} from '@angular/core'\nimport {Observable} from 'rxjs'\nimport {share} from 'rxjs/operators'\n//noinspection ES6PreferShortImport\nimport {generatePushID} from '../util/generate-push-id'\n\nexport type BusMessageIntent = 'request' | 'action' | 'event' | 'notification' | 'log'\n\nexport const Intention = {\n /**\n * An action has been performed. For example, a user has been created, granted a permission, removed, etc.\n */\n action: <BusMessageIntent>'action',\n\n /**\n * A general event, typically used to communicate UI state across domains.\n */\n event: <BusMessageIntent>'event',\n\n /**\n * A BusMessage whose intent is to record a log message.\n */\n log: <BusMessageIntent>'log',\n\n /**\n * A BusMessage whose intent is to provide a message to the Visitor. It is up to the currently active UI to determine the best method\n * of sharing the message payload.\n */\n notification: <BusMessageIntent>'notification',\n\n /**\n * A BusMessage that communicates that the current Visitor has requested than an action be performed. For example, clicked a button\n * that is intended to result in a user being created, a permission being granted, etc.\n */\n request: <BusMessageIntent>'request',\n}\n\n\nexport class BusMessage {\n public id: string\n public intent: BusMessageIntent\n public key: string\n public source: string\n\n /** @todo: 'intent' should probably be handled by static creation methods. */\n constructor(source: string, intent?: BusMessageIntent, key?: string) {\n this.id = generatePushID()\n this.source = source\n this.intent = intent || 'event' // this should not be optional.\n this.key = key || '_'\n }\n}\n\n@Injectable()\nexport class MessageBus {\n\n public all: Observable<BusMessage>\n private bus: EventEmitter<BusMessage> = new EventEmitter(false)\n\n constructor() {\n this.all = this.bus.pipe(share());\n }\n\n post(message: BusMessage) {\n this.bus.next(message)\n }\n}\n","import {BusMessage} from '../message-bus'\nimport {LogLevel} from './logger'\n\nexport class LogMessage extends BusMessage {\n static SourceKey:string = \"LogMessage\"\n context?: any\n message: any[]\n level: LogLevel\n\n constructor(level: LogLevel, context: any, ...message: any[]) {\n super(LogMessage.SourceKey, 'log')\n this.message = message\n this.context = context\n this.level = level\n }\n\n}\n","import {\n Injectable,\n Optional\n} from '@angular/core'\nimport {LogMessage} from './log-message'\n\nconst spaces = ' '\n\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'NONE'\n\n/**\n *\n *\n */\nexport const LogLevels = {\n NONE: <LogLevel>'NONE',\n fatal: <LogLevel>'fatal',\n error: <LogLevel>'error',\n warn: <LogLevel>'warn',\n info: <LogLevel>'info',\n debug: <LogLevel>'debug',\n trace: <LogLevel>'trace'\n}\n\nexport class LoggerConfiguration {\n contextAsStringWidth: number = 30\n includeFullContext: boolean = false\n /**\n * For temporarily shutting of logging, use NONE, but if you are shutting off logging for production, or because you're using\n * another logging system, you should Provide a simpler logging class in your module configuration.\n * @type {LogLevel}\n */\n logLevel: LogLevel = 'trace'\n}\n\nconst emptyFn = function (...x: any[]): any {}\n\n\n@Injectable()\nexport abstract class Logger {\n\n config: LoggerConfiguration = new LoggerConfiguration()\n\n protected constructor(@Optional() configuration?: LoggerConfiguration) {\n this.config = configuration || this.config\n this.applyLevel()\n }\n\n abstract log(message: LogMessage): void\n\n trace(context: any, ...message:any[]) {\n this.log(new LogMessage('trace', context, ...message))\n }\n\n debug(context: any, ...message:any[]) {\n this.log(new LogMessage('debug', context, ...message))\n }\n\n info(context: any, ...message:any[]) {\n this.log(new LogMessage('info', context, ...message))\n }\n\n warn(context: any, ...message:any[]) {\n this.log(new LogMessage('warn', context, ...message))\n }\n\n error(context: any, ...message:any[]) {\n this.log(new LogMessage('error', context, ...message))\n }\n\n fatal(context: any, ...message:any[]) {\n this.log(new LogMessage('fatal', context, ...message))\n }\n\n\n private applyLevel() {\n console.log('Logger', 'applyLevel', this.config)\n /**\n * This keeps noise off the system bus when running in production mode or with logging off.\n * Yes, it's supposed to fall through, despite the evil nature.\n */\n // @ts-ignore\n // noinspection FallThroughInSwitchStatementJS\n switch (this.config.logLevel) {\n // @ts-ignore\n case LogLevels.NONE:\n this.fatal = emptyFn\n // @ts-ignore\n case LogLevels.fatal:\n this.error = emptyFn\n // @ts-ignore\n case LogLevels.error:\n this.warn = emptyFn\n // @ts-ignore\n case LogLevels.warn:\n this.info = emptyFn\n // @ts-ignore\n case LogLevels.info:\n this.debug = emptyFn\n // @ts-ignore\n case LogLevels.debug:\n this.trace = emptyFn\n // @ts-ignore\n }\n }\n\n}\n","import {\n Injectable,\n Optional\n} from '@angular/core'\nimport {LogMessage} from './log-message'\nimport {\n LoggerConfiguration,\n Logger\n} from './logger'\n\nconst spaces = ' '\n\n\n/**\n * Singleton. Attempting to run two Logger instances will fail. And rightly so!\n */\n@Injectable()\nexport class ConsoleLogger extends Logger {\n\n constructor(@Optional() configuration?: LoggerConfiguration) {\n super(configuration)\n }\n\n log(message: LogMessage) {\n let args = [message.level + ':']\n let name: string = ''\n if (message.context && !this.config.includeFullContext && message.context.constructor) {\n name = message.context._proto_ ? message.context._proto_.name : message.context.constructor.name\n }\n const padChars = this.config.contextAsStringWidth - name.length\n name = padChars > 0 ? name + spaces.substring(0, padChars) : name\n args.push(name + ' - ')\n args = args.concat(message.message)\n\n if (this.config.includeFullContext && message.context) {\n args.push(message.context)\n }\n\n console.log.apply(console, args)\n }\n\n\n\n}\n","import {\n Injectable,\n Optional\n} from '@angular/core'\nimport {MessageBus} from '../message-bus'\nimport {LogMessage} from './log-message'\nimport {\n LoggerConfiguration,\n LogLevels\n} from './logger'\nimport {ConsoleLogger} from './console-logger'\n\n@Injectable()\nexport class BusLoggerConfiguration extends LoggerConfiguration {\n alsoLogToConsole:boolean = false\n}\n\n/**\n * Singleton. Attempting to run two Logger instances will fail. And rightly so!\n */\n@Injectable()\nexport class BusLogger extends ConsoleLogger {\n\n override config:BusLoggerConfiguration = new BusLoggerConfiguration()\n\n constructor(private bus: MessageBus, @Optional() configuration?: LoggerConfiguration) {\n super(configuration)\n console.log('BusLogger', 'constructor', configuration)\n }\n\n override log(message: LogMessage): void {\n this.bus.post(message)\n if(this.config.alsoLogToConsole){\n super.log(message)\n }\n }\n}\n","import {Observable} from 'rxjs'\nimport {filter} from 'rxjs/operators'\nimport {\n BusMessage,\n MessageBus\n} from '../message-bus'\n\n\nexport class NavigationMessage extends BusMessage {\n static SourceKey = 'NavigationMessage'\n path: string\n additionalMessage: string | undefined\n constructor(key:string, path: string, additionalMessage?:string) {\n super(NavigationMessage.SourceKey, 'notification', key)\n this.path = path\n this.additionalMessage = additionalMessage\n }\n\n static filter(bus: MessageBus):Observable<BusMessage> {\n return bus.all.pipe(filter(m => m.source === NavigationMessage.SourceKey))\n }\n}\n\n\nexport class NavigationRequiresAuthenticationMessage extends NavigationMessage {\n static Key: string = 'requiresAuthentication'\n\n constructor(path: string) {\n super(NavigationRequiresAuthenticationMessage.Key, path)\n }\n\n static post(bus: MessageBus, path: string) {\n bus.post(new NavigationRequiresAuthenticationMessage(path))\n }\n}\n\nexport class NavigationRequiresRoleMessage extends NavigationMessage {\n static Key: string = 'requiresRole'\n\n constructor(path: string, public roleKey: string) {\n super(NavigationRequiresRoleMessage.Key, path, 'Role Required: ' + roleKey)\n }\n\n static post(bus: MessageBus, path: string, roleKey: string) {\n bus.post(new NavigationRequiresRoleMessage(path, roleKey))\n }\n}\n\n\nexport class NavigationRequiresPermissionMessage extends NavigationMessage {\n static SubKey: string = 'requiresPermission'\n\n constructor(path: string, public permissionKey: string) {\n super(NavigationRequiresPermissionMessage.SubKey, path, 'Permission Required: ' + permissionKey)\n }\n\n\n static post(bus: MessageBus, path: string, roleKey: string) {\n bus.post(new NavigationRequiresPermissionMessage(path, roleKey))\n }\n\n\n}\n\n\n\n\n","import {filter, Observable} from 'rxjs'\nimport {BusMessage, BusMessageIntent, MessageBus} from '../message-bus'\n\nexport class AppMessage extends BusMessage {\n static SourceKey: string = 'App'\n\n static SignOutRequest = 'signOutRequest'\n\n constructor(intent:BusMessageIntent, key:string) {\n super(AppMessage.SourceKey, intent, key)\n }\n\n static filter(bus:MessageBus):Observable<AppMessage>{\n return bus.all.pipe(filter(msg => msg.source === AppMessage.SourceKey))\n }\n\n static signOutRequest() {\n return new AppMessage('request', AppMessage.SignOutRequest)\n }\n}\n","export interface PageInfo {\n title: string\n}\n\nexport interface PageAnalyticsEvents {\n load?: boolean\n unload?: boolean\n scroll?: boolean\n click?: boolean\n mouseMove?: boolean\n}\n\nexport interface PageAnalytics {\n events?: PageAnalyticsEvents\n}\n\nexport interface RouteInfo {\n page?: PageInfo\n analytics?: PageAnalytics\n showAds?: boolean\n}\n\nexport const DefaultPageAnalytics = function (): PageAnalytics {\n return {\n events: {\n load: true,\n unload: true\n }\n }\n}\n","import {\n ActivatedRoute,\n Route,\n Router\n} from '@angular/router'\n\nexport class NgRouteUtil {\n\n static fullPath(route: ActivatedRoute):string {\n let pathAry:string[] = []\n route.pathFromRoot\n .map(routeSegment => routeSegment.snapshot)\n .map(routeSnap => {\n return routeSnap\n })\n .map(routeSnap => routeSnap.url)\n .filter(segments => segments && segments.length > 0)\n .forEach(segments => segments.forEach(segment => pathAry.push(segment.toString())))\n\n let path = pathAry.join('/')\n\n if (path && path.endsWith('/')) {\n path = path.substring(0, path.length - 1)\n }\n return path\n }\n\n static primaryLeaf(router: Router): ActivatedRoute {\n let c = router.routerState.root\n while (c.firstChild) {\n c = c.firstChild\n }\n return c\n }\n\n static findDescendantByComponentKey(router: Router, componentTypeKey: string): (ActivatedRoute | null ) {\n let c:ActivatedRoute | null = router.routerState.root\n do {\n if (c.component && (c.component as any)['Key'] == componentTypeKey) {\n break\n }\n c = c.firstChild\n } while (c)\n return c\n }\n\n\n /**\n * Breadth first search of route to find the descendant where 'parent.children[x].component['Key'] === componentTypeKey'\n * This requires that the Component have the static field 'Key' declared and set to a value.\n * @param route\n * @param componentTypeKey\n * @returns {Route | null}\n */\n static findDescendantRouteByComponentKey(route: Route, componentTypeKey: string): (Route | null ) {\n let result = null\n if (route.children) {\n for (let i = 0; i < route.children.length; i++) {\n let child = route.children[i]\n if (child.component && (child.component as any)['Key'] === componentTypeKey) {\n result = child\n break\n }\n }\n if (!result) {\n for (let i = 0; i < route.children.length; i++) {\n result = NgRouteUtil.findDescendantRouteByComponentKey(route.children[i], componentTypeKey)\n if (result) {\n break\n }\n }\n }\n }\n return result\n }\n\n /**\n * Breadth first search of route to find the descendant where 'parent.children[x].path === path'\n * @param route\n * @param path\n * @returns {Route | null}\n */\n static findDescendantRouteByPath(route: Route, path: string): (Route | null ) {\n let result = null\n if (route.children) {\n for (let i = 0; i < route.children.length; i++) {\n let child = route.children[i]\n if (child.path === path) {\n result = child\n break\n }\n }\n if (!result) {\n for (let i = 0; i < route.children.length; i++) {\n result = NgRouteUtil.findDescendantRouteByPath(route.children[i], path)\n if (result) {\n break\n }\n }\n }\n }\n return result\n }\n\n}\n","export interface TimeUnit {\n unitKey: string\n logicalMax: number\n fullLabel: string\n label: string\n momentKey: 'd' | 'h' | 'm' | 's' | 'ms',\n orderIndex: number\n separatorSuffix: string\n next: string | undefined\n previous: string | undefined\n}\n\n\nexport const TimeUnitSort = (b:TimeUnit, a:TimeUnit) => {\n return a.orderIndex - b.orderIndex\n}\nexport interface TimeUnitsType {\n day: TimeUnit,\n h: TimeUnit,\n min: TimeUnit,\n s: TimeUnit,\n ms: TimeUnit,\n}\nexport const TimeUnits:TimeUnitsType = {\n day: <TimeUnit>{\n unitKey: 'day',\n fullLabel: 'Day',\n label: 'day',\n separatorSuffix: 'd ',\n logicalMax: 7,\n momentKey: 'd',\n orderIndex: 40,\n next: 'h',\n previous: undefined\n },\n h: <TimeUnit>{\n unitKey: 'h',\n fullLabel: 'Hour',\n label: 'hour',\n separatorSuffix: ':',\n logicalMax: 23,\n momentKey: 'h',\n orderIndex: 30,\n next: 'min',\n previous: 'day'\n } ,\n min: <TimeUnit>{\n unitKey: 'min',\n fullLabel: 'Minute',\n label: 'min',\n separatorSuffix: ':',\n logicalMax: 59,\n momentKey: 'm',\n orderIndex: 20,\n next: 's',\n previous: 'h'\n },\n s: <TimeUnit>{\n unitKey: 's',\n fullLabel: 'Second',\n label: 'sec',\n separatorSuffix: '.',\n logicalMax: 59,\n momentKey: 's',\n orderIndex: 10,\n next: 'ms',\n previous: 'min'\n },\n ms: <TimeUnit>{\n unitKey: 'ms',\n fullLabel: 'Millisecond',\n label: 'ms',\n separatorSuffix: '',\n logicalMax: 999,\n momentKey: 'ms',\n orderIndex: 0,\n next: undefined,\n previous: 's'\n },\n}\n\nexport const TimeUnitKeySort = (a:keyof TimeUnitsType, b:keyof TimeUnitsType) => {\n return TimeUnits[b].orderIndex - TimeUnits[a].orderIndex\n}\n\n","import {ChangeDetectorRef} from '@angular/core'\nexport class Hacks {\n static materialDesignPlaceholderText(changeDetector: ChangeDetectorRef) {\n setTimeout(() => {\n changeDetector.markForCheck()\n }, 100)\n }\n}\n","export class LocalizationUtil {\n\n static browserLanguages(): string[] {\n let languages:string[]\n if (navigator['languages']) {\n languages = navigator['languages'] as string[]\n } else {\n languages = [navigator.language]\n }\n\n return languages\n }\n\n}\n","const adjectives: string[] = [\n 'Abrupt', 'Acidic', 'Adorable', 'Adventurous', 'Aggressive', 'Agitated', 'Alert', 'Aloof', 'Amiable', 'Amused',\n 'Annoyed', 'Antsy', 'Anxious', 'Appalling', 'Appetizing', 'Apprehensive', 'Arrogant', 'Astonishing', 'Attractive',\n 'Batty', 'Beefy', 'Bewildered', 'Biting', 'Bitter', 'Bland', 'Blushing', 'Bored', 'Brave', 'Bright', 'Broad', 'Bulky',\n 'Burly', 'Charming', 'Cheeky', 'Cheerful', 'Clean', 'Clear', 'Cloudy', 'Clueless', 'Clumsy', 'Colorful', 'Colossal',\n 'Combative', 'Comfortable', 'Confused', 'Contemplative', 'Convincing', 'Convoluted', 'Cooperative', 'Corny', 'Costly',\n 'Courageous', 'Crabby', 'Creepy', 'Crooked', 'Cumbersome', 'Cynical', 'Dangerous', 'Dashing', 'Deep', 'Defeated',\n 'Defiant', 'Delicious', 'Delightful', 'Depraved', 'Despicable', 'Determined', 'Dilapidated', 'Diminutive',\n 'Disgusted', 'Distinct', 'Distraught', 'Distressed', 'Disturbed', 'Dizzy', 'Drab', 'Drained', 'Dull', 'Eager',\n 'Ecstatic', 'Elated', 'Elegant', 'Embarrassed', 'Enchanting', 'Encouraging', 'Energetic', 'Enormous', 'Enthusiastic',\n 'Envious', 'Exasperated', 'Excited', 'Exhilarated', 'Extensive', 'Exuberant', 'Fancy', 'Fantastic', 'Fierce',\n 'Filthy', 'Flat', 'Floppy', 'Fluttering', 'Foolish', 'Frantic', 'Fresh', 'Friendly', 'Frothy', 'Frustrating', 'Funny',\n 'Fuzzy', 'Gaudy', 'Gentle', 'Giddy', 'Gigantic', 'Glamorous', 'Gleaming', 'Glorious', 'Gorgeous', 'Graceful',\n 'Gritty', 'Grubby', 'Grumpy', 'Handsome', 'Happy', 'Harebrained', 'Healthy', 'Helpful', 'Hollow', 'Homely', 'Huge',\n 'Icy', 'Ideal', 'Immense', 'Impressionable', 'Intrigued', 'Itchy', 'Jealous', 'Jittery', 'Jolly', 'Joyous', 'Juicy',\n 'Jumpy', 'Kind', 'Lackadaisical', 'Lazy', 'Little', 'Lively', 'Livid', 'Lonely', 'Loose', 'Lovely', 'Lucky',\n 'Ludicrous', 'Macho', 'Magnificent', 'Mammoth', 'Maniacal', 'Massive', 'Melancholy', 'Melted', 'Miniature', 'Minute',\n 'Mistaken', 'Misty', 'Moody', 'Muddy', 'Mysterious', 'Narrow', 'Naughty', 'Nervous', 'Nonchalant', 'Nonsensical',\n 'Nutritious', 'Nutty', 'Oblivious', 'Obnoxious', 'Odd', 'Old-fashioned', 'Outrageous', 'Perfect', 'Perplexed',\n 'Petite', 'Petty', 'Plain', 'Pleasant', 'Poised', 'Pompous', 'Precious', 'Prickly', 'Proud', 'Pungent', 'Puny',\n 'Quaint', 'Quizzical', 'Ratty', 'Reassured', 'Relieved', 'Responsive', 'Ripe', 'Robust', 'Rough', 'Round', 'Salty',\n 'Sarcastic', 'Scant', 'Scary', 'Scattered', 'Scrawny', 'Selfish', 'Shaggy', 'Shaky', 'Shallow', 'Sharp', 'Shiny',\n 'Short', 'Silky', 'Silly', 'Skinny', 'Slippery', 'Small', 'Smarmy', 'Smiling', 'Smoggy', 'Smooth', 'Smug', 'Soggy',\n 'Solid', 'Sore', 'Sour', 'Sparkling', 'Spicy', 'Splendid', 'Spotless', 'Square', 'Stale', 'Steady', 'Steep', 'Sticky',\n 'Stormy', 'Stout', 'Strange', 'Strong', 'Stunning', 'Substantial', 'Successful', 'Succulent', 'Superficial',\n 'Superior', 'Swanky', 'Sweet', 'Tart', 'Tasty', 'Teeny', 'Tender', 'Tense', 'Terrible', 'Testy', 'Thankful', 'Thick',\n 'Thoughtful', 'Thoughtless', 'Timely', 'Tricky', 'Trite', 'Pated', 'Uneven', 'Unsightly', 'Upset', 'Uptight', 'Vast',\n 'Vexed', 'Victorious', 'Virtuous', 'Vivacious', 'Vivid', 'Wacky', 'Whimsical', 'Whopping', 'Wicked', 'Witty',\n 'Wobbly', 'Wonderful', 'Worried', 'Yummy', 'Zany', 'Zealous', 'Zippy'];\n\n\nconst nouns: string[] = [\n 'Aardvark', 'Aardwolf', 'Albatross', 'Alligator', 'Alpaca', 'Anaconda', 'Anglerfish', 'Ant', 'Anteater', 'Antelope',\n 'Antlion', 'Ape', 'Aphid', 'Armadillo', 'Asp', 'Baboon', 'Badger', 'Bandicoot', 'Barnacle', 'Barracuda', 'Basilisk',\n 'Bass', 'Bat', 'Bear', 'Beaver', 'Bedbug', 'Bee', 'Beetle', 'Bison', 'Blackbird', 'Boa', 'Bobcat', 'Bobolink',\n 'Bonobo', 'Booby', 'Bovid', 'Buffalo', 'Bug', 'Butterfly', 'Buzzard', 'Camel', 'Canid', 'Capybara', 'Cardinal',\n 'Caribou', 'Carp', 'Caterpillar', 'Catfish', 'Catshark', 'Centipede', 'Cephalopod', 'Chameleon', 'Cheetah',\n 'Chickadee', 'Chimpanzee', 'Chinchilla', 'Chipmunk', 'Cicada', 'Clam', 'Clownfish', 'Cobra', 'Cockroach', 'Cod',\n 'Condor', 'Constrictor', 'Coral', 'Cougar', 'Cow', 'Coyote', 'Coypu', 'Crab', 'Crane', 'Crawdad', 'Crayfish',\n 'Cricket', 'Crocodile', 'Crow', 'Cuckoo', 'Damselfly', 'Deer', 'Dingo', 'Dolphin', 'Dormouse', 'Dove', 'Dragon',\n 'Dragonfly', 'Eagle', 'Earthworm', 'Earwig', 'Echidna', 'Eel', 'Egret', 'Elephant', 'Elk', 'Emu', 'Ermine', 'Falcon',\n 'Ferret', 'Finch', 'Firefly', 'Fish', 'Flamingo', 'Flea', 'Fly', 'Flyingfish', 'Fowl', 'Fox', 'Fox', 'Frog',\n 'Gazelle', 'Gecko', 'Gerbil', 'Gibbon', 'Giraffe', 'Goldfish', 'Gopher', 'Gorilla', 'Grasshopper', 'Grouse',\n 'Guanaco', 'Gull', 'Guppy', 'Haddock', 'Halibut', 'Hamster', 'Hare', 'Harrier', 'Hawk', 'Hedgehog', 'Heron',\n 'Herring', 'Hippopotamus', 'Hookworm', 'Hornet', 'Hoverfly', 'Hummingbird', 'Hyena', 'Iguana', 'Impala', 'Insect',\n 'Jacana', 'Jackal', 'Jaguar', 'Jay', 'Jellyfish', 'Junglefowl', 'Kangaroo', 'Kingfisher', 'Kite', 'Kiwi', 'Koala',\n 'Koi', 'Krill', 'Ladybug', 'Lamprey', 'Landfowl', 'Lark', 'Leech', 'Lemming', 'Lemur', 'Leopard', 'Leopard',\n 'Leopard', 'Leopon', 'Limpet', 'Lion', 'Lizard', 'Llama', 'Lobster', 'Locust', 'Loon', 'Louse', 'Lungfish', 'Lynx',\n 'Macaw', 'Mackerel', 'Magpie', 'Mammal', 'Manatee', 'Mandrill', 'Marlin', 'Marmoset', 'Marmot', 'Marsupial', 'Marten',\n 'Mastodon', 'Meadowlark', 'Meerkat', 'Mink', 'Minnow', 'Mite', 'Mockingbird', 'Mole', 'Mollusk', 'Mongoose', 'Monkey',\n 'Moose', 'Mosquito', 'Moth', 'Mouse', 'Mule', 'Muskox', 'Narwhal', 'Needlefish', 'Newt', 'Nighthawk', 'Nightingale',\n 'Numbat', 'Ocelot', 'Octopus', 'Okapi', 'Olingo', 'Opossum', 'Orangutan', 'Orca', 'Oribi', 'Ostrich', 'Otter', 'Owl',\n 'Ox', 'Panda', 'Panther', 'Panther', 'Parakeet', 'Parrot', 'Parrotfish', 'Partridge', 'Peacock', 'Peafowl', 'Pelican',\n 'Penguin', 'Perch', 'Pheasant', 'Pig', 'Pike', 'Pinniped', 'Piranha', 'Planarian', 'Platypus', 'Pony', 'Porcupine',\n 'Porpoise', 'Possum', 'Prawn', 'Primate', 'Ptarmigan', 'Puffin', 'Puma', 'Python', 'Quail', 'Quelea', 'Quokka',\n 'Raccoon', 'Rat', 'Rattlesnake', 'Raven', 'Reindeer', 'Reptile', 'Rhinoceros', 'Roadrunner', 'Rodent', 'Rook',\n 'Rooster', 'Roundworm', 'Sailfish', 'Salamander', 'Salmon', 'Sawfish', 'Scallop', 'Scorpion', 'Seahorse', 'Shrew',\n 'Shrimp', 'Silkworm', 'Silverfish', 'Skink', 'Skunk', 'Sloth', 'Slug', 'Smelt', 'Snail', 'Snipe', 'Sole', 'Sparrow',\n 'Spider', 'Spoonbill', 'Squid', 'Squirrel', 'Starfish', 'Stingray', 'Stoat', 'Stork', 'Sturgeon', 'Swallow', 'Swan',\n 'Swift', 'Swordfish', 'Swordtail', 'Tahr', 'Takin', 'Tapir', 'Tarantula', 'Tarsier', 'Termite', 'Tern', 'Thrush',\n 'Tick', 'Tiger', 'Tiglon', 'Titi', 'Toad', 'Tortoise', 'Toucan', 'Trout', 'Tuna', 'Turtle', 'Tyrannosaurus', 'Urial',\n 'Vaquita', 'Vicuña', 'Viper', 'Voalavoanala', 'Vole', 'Vulture', 'Wallaby', 'Walrus', 'Warbler', 'Wasp', 'Waterbuck',\n 'Weasel', 'Whale', 'Whippet', 'Whitefish', 'Wildcat', 'Wildebeest', 'Wildfowl', 'Wolf', 'Wolf', 'Wolverine', 'Wombat',\n 'Woodchuck', 'Woodpecker', 'Worm', 'Wren', 'Xerinae', 'Yak', 'Zebra', 'Zebu', 'Zorilla',\n]\n\n\nexport class NameGenerator {\n static adjectivesLength = adjectives.length\n static nounsLength = nouns.length\n\n static generate() {\n const aRand = Math.floor(NameGenerator.adjectivesLength * Math.random())\n const nRand = Math.floor(NameGenerator.nounsLength * Math.random())\n\n return adjectives[aRand] + ' ' + nouns[nRand]\n }\n}\n","import {ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';\nimport {Observable} from 'rxjs';\nimport {map} from 'rxjs/operators'\n\n\n\nexport class NgUtil {\n\n static data$(route: ActivatedRoute):Observable<{}> {\n return route.data.pipe(map((data: any) => {\n return NgUtil.collectFromRoute(route.snapshot, true)\n }))\n }\n\n static data(route: ActivatedRouteSnapshot): any {\n return NgUtil.collectFromRoute(route, true)\n }\n\n static params(route: ActivatedRouteSnapshot): any {\n return NgUtil.collectFromRoute(route, false)\n }\n\n static collectFromRoute(route: ActivatedRouteSnapshot, data: boolean): any {\n const datas: any[] = [{}]\n let child:ActivatedRouteSnapshot|null = route.root\n while (child) {\n const what = data ? child.data : child.params\n datas.push(what || {})\n child = child.firstChild\n }\n // merge them all together...\n return Object.assign.apply(Object, datas as any) as any\n }\n\n static params$(route: ActivatedRoute) {\n return route.params.pipe(map((params: any) => {\n return NgUtil.collectFromRoute(route.snapshot, false)\n }))\n }\n\n static routeLeaf(route: RouterStateSnapshot): ActivatedRouteSnapshot {\n let child = route.root\n\n while (child.firstChild) {\n child = child.firstChild\n }\n return child\n }\n\n static keylessUrl(route: RouterStateSnapshot): string {\n return route.url ? route.url.split('/').map(\n segment => NgUtil.isFirebaseId(segment) ? ':key' : segment).join('/') : ''\n }\n\n /**\n *\n * @param key\n * @returns {boolean}\n * @deprecated See FireBlanket.util#isFirebaseGeneratedId\n */\n static isFirebaseId(key: string): boolean {\n let isKey = false\n if (key && key.length === 20 && key.startsWith('-')) {\n isKey = true\n }\n return isKey\n }\n\n}\n","import {ObjectUtil} from './core-util';\nexport class TransformUtil {\n\n\n static firstExisting(...obj: any[]) {\n let result\n for (let i = 0; i < obj.length; i++) {\n if(ObjectUtil.exists(obj[i])){\n result = obj[i]\n break\n }\n }\n return result\n }\n}\n","// noinspection ES6PreferShortImport\nimport {MessageBus} from '../message-bus/message-bus';\n// noinspection ES6PreferShortImport\nimport {RouteInfo} from '../routing/route-info';\n\n/**\n * Cannot implement 'OnInit' any longer; Angular inspects for that and requires a decorator.\n */\nexport abstract class Page {\n\n public routeInfo: RouteInfo\n\n protected constructor(protected bus:MessageBus) {\n this.routeInfo = {\n page: {\n title: this.constructor['name']\n },\n showAds: false\n }\n }\n\n}\n","/*\n * Public API Surface of core\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["spaces","i1.LoggerConfiguration","i1.MessageBus","i2.LoggerConfiguration","filter"],"mappings":"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