hidden const powerOfTwo = [ 0x1 , 0x2 , 0x4 , 0x8 , 0x10 , 0x20 , 0x40 , 0x80 , 0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 , 0x10000 , 0x20000 , 0x40000 , 0x80000 , 0x100000 , 0x200000 , 0x400000 , 0x800000 , 0x1000000 , 0x2000000 , 0x4000000 , 0x8000000 , 0x10000000 , 0x20000000 , 0x40000000 , 0x80000000 , 0x100000000 , 0x200000000 , 0x400000000 , 0x800000000 , 0x1000000000 , 0x2000000000 , 0x4000000000 , 0x8000000000 , 0x10000000000 , 0x20000000000 , 0x40000000000 , 0x80000000000 , 0x100000000000 , 0x200000000000 , 0x400000000000 , 0x800000000000 , 0x1000000000000 , 0x2000000000000 , 0x4000000000000 , 0x8000000000000 , 0x10000000000000 ] ; /**
 * The `TileKey` instances are used to address a tile in a quadtree.
 *
 * A tile key is defined by a row, a column, and a level. The tree has a root at level 0, with one
 * single tile. On every level, each tile is divided into four children (therefore the name
 * quadtree).
 *
 * Within each [[level]], any particular tile is addressed with [[row]] and [[column]]. The number
 * of rows and columns in each level is 2 to the power of the level. This means: On level 0, only
 * one tile exists, [[columnsAtLevel]]() and [[rowsAtLevel]]() are both 1. On level 1, 4 tiles
 * exist, in 2 rows and 2 columns. On level 2 we have 16 tiles, in 4 rows and 4 columns. And so on.
 *
 * A tile key is usually created using [[fromRowColumnLevel]]() method.
 *
 * `TileKey` instances are immutable, all members return new instances of `TileKey` and do not
 * modify the original object.
 *
 * Utility functions like [[parent]](), [[changedLevelBy]](), and [[changedLevelTo]]() allow for
 * easy vertical navigation of the tree. The number of available rows and columns in the tile's
 * level is given with [[rowCount]]() and [[columnCount]]().
 *
 * Tile keys can be created from and converted into various alternative formats:
 *
 *  - [[toQuadKey]]() / [[fromQuadKey]]() - string representation 4-based
 *  - [[toHereTile]]() / [[fromHereTile]]() - string representation 10-based
 *  - [[mortonCode]]() / [[fromMortonCode]]() - number representation
 *
 * Note - as JavaScript's number type can hold 53 bits in its mantissa, only levels up to 26 can be
 * represented in the number representation returned by [[mortonCode]]().
 */ export class TileKey { param row param column param level static fromRowColumnLevel ( row , column , level ) { return new TileKey ( row , column , level ) ; } param quadkey returns static fromQuadKey ( quadkey ) { const level = quadkey . length ; let row = 0 ; let column = 0 ; for ( let i = 0 ; i < quadkey . length ; ++ i ) { const mask = 1 << i ; const d = parseInt ( quadkey . charAt ( level - i - 1 ) , 10 ) ; if ( d & 0x1 ) { column |= mask ; } if ( d & 0x2 ) { row |= mask ; } } return TileKey . fromRowColumnLevel ( row , column , level ) ; } param quadKey64 returns A new instance of  TileKey .
      static fromMortonCode ( quadKey64 ) { let level = 0 ; let row = 0 ; let column = 0 ; let quadKey = quadKey64 ; while ( quadKey > 1 ) { const mask = 1 << level ; if ( quadKey & 0x1 ) { column |= mask ; } if ( quadKey & 0x2 ) { row |= mask ; } level ++ ; quadKey = ( quadKey - ( quadKey & 0x3 ) ) / 4 ; } const result = TileKey . fromRowColumnLevel ( row , column , level ) ; result . m_mortonCode = quadKey64 ; return result ; } param quadkey64 returns static fromHereTile ( quadkey64 ) { const result = TileKey . fromMortonCode ( parseInt ( quadkey64 , 10 ) ) ; result . m_hereTile = quadkey64 ; return result ; } param level returns static columnsAtLevel ( level ) { return Math . pow ( 2 , level ) ; } param level returns static rowsAtLevel ( level ) { return Math . pow ( 2 , level ) ; } param level param coordX param coordY param totalWidth param totalHeight returns static atCoords ( level , coordX , coordY , totalWidth , totalHeight ) { return TileKey . fromRowColumnLevel ( Math . floor ( coordY / ( totalHeight / TileKey . rowsAtLevel ( level ) ) ) , Math . floor ( coordX / ( totalWidth / TileKey . columnsAtLevel ( level ) ) ) , level ) ; } param mortonCode returns static parentMortonCode ( mortonCode ) { return Math . floor ( mortonCode / 4 ) ; } private m_mortonCode ? : number ; private m_hereTile ? : string ; /**
     * Constructs a new immutable instance of a `TileKey`.
     *
     * For the better readability,  TileKey . fromRowColumnLevel should be preferred.
     *
     * Note - row and column must not be greater than the maximum rows/columns for the given level.
     *
     *  param row param column param level constructor ( readonly row , readonly column , readonly level ) { } /**
     * Returns a tile key representing the parent of the tile addressed by this tile key.
     *
     * Throws an exception is this tile is already the root.
     */ parent ( ) { if ( this . level === 0 ) { throw new Error ( "Cannot get the parent of the root tile key" ) ; } return TileKey . fromRowColumnLevel ( this . row >>> 1 , this . column >>> 1 , this . level - 1 ) ; } param delta changedLevelBy ( delta ) { const level = Math . max ( 0 , this . level + delta ) ; let row = this . row ; let column = this . column ; if ( delta >= 0 ) { row <<= delta ; column <<= delta ; } else { row >>>= - delta ; column >>>= - delta ; } return TileKey . fromRowColumnLevel ( row , column , level ) ; } param level changedLevelTo ( level ) { return this . changedLevelBy ( level - this . level ) ; } /**
     * Converts the tile key to a numeric code representation.
     *
     * You can create a tile key from a numeric Morton code with [[fromMortonCode]].
     *
     * Note - only levels <= 26 are supported.
     */ mortonCode ( ) { if ( this . m_mortonCode === undefined ) { let column = this . column ; let row = this . row ; let result = powerOfTwo [ this . level << 1 ] ; for ( let i = 0 ; i < this . level ; ++ i ) { if ( column & 0x1 ) { result += powerOfTwo [ 2 * i ] ; } if ( row & 0x1 ) { result += powerOfTwo [ 2 * i + 1 ] ; } column >>>= 1 ; row >>>= 1 ; } this . m_mortonCode = result ; } return this . m_mortonCode ; } /**
     * Converts the tile key into a string for using in REST API calls.
     *
     * The string is a quadkey Morton code representation as a string.
     *
     * You can convert back from a quadkey string with [[fromHereTile]].
     */ toHereTile ( ) { if ( this . m_hereTile === undefined ) { this . m_hereTile = this . mortonCode ( ) . toString ( ) ; } return this . m_hereTile ; } /**
     * Converts the tile key into a string for using in REST API calls.
     *
     * If the tile is the root tile, the quadkey is '-'. Otherwise the string is a number to the
     * base of 4, but without the leading 1, with the following properties:
     *  1. the number of digits equals the level.
     *  2. removing the last digit gives the parent tile's quadkey string, i.e. appending 0,1,2,3
     *     to a quadkey string gives the tiles's children.
     *
     * You can convert back from a quadkey string with [[fromQuadKey]].
     */ toQuadKey ( ) { let result = "" ; for ( let i = this . level ; i > 0 ; -- i ) { const mask = 1 << ( i - 1 ) ; const col = ( this . column & mask ) !== 0 ; const row = ( this . row & mask ) !== 0 ; if ( col && row ) { result += "3" ; } else if ( row ) { result += "2" ; } else if ( col ) { result += "1" ; } else { result += "0" ; } } return result ; } param qnr returns equals ( qnr ) { return this . row === qnr . row && this . column === qnr . column && this . level === qnr . level ; } param sub returns addedSubKey ( sub ) { const subQuad = TileKey . fromQuadKey ( sub . length === 0 ? "-" : sub ) ; const child = this . changedLevelBy ( subQuad . level ) ; return TileKey . fromRowColumnLevel ( child . row + subQuad . row , child . column + subQuad . column , child . level ) ; } param sub returns addedSubHereTile ( sub ) { const subQuad = TileKey . fromHereTile ( sub ) ; const child = this . changedLevelBy ( subQuad . level ) ; return TileKey . fromRowColumnLevel ( child . row + subQuad . row , child . column + subQuad . column , child . level ) ; } param delta returns getSubHereTile ( delta ) { const key = this . mortonCode ( ) ; const msb = 1 << ( delta * 2 ) ; const mask = msb - 1 ; const result = ( key & mask ) | msb ; return result . toString ( ) ; } /**
     * Returns the number of available rows in the tile's [[level]].
     *
     * This is 2 to the power of the level.
     */ rowCount ( ) { return TileKey . rowsAtLevel ( this . level ) ; } /**
     * Returns the number of available columns in the tile's [[level]].
     *
     * This is 2 to the power of the level.
     */ columnCount ( ) { return TileKey . columnsAtLevel ( this . level ) ; } }