function pure(node, withChildren, after) {
      var _this2 = this;

      var t = assign$1({}, node);

      delete t._id;
      delete t.parent;
      delete t.children;
      delete t.open;
      delete t.active;
      delete t.style;
      delete t.class;
      delete t.innerStyle;
      delete t.innerClass;
      delete t.innerBackStyle;
      delete t.innerBackClass;

      var _arr = keys$1(t);

      for (var _i = 0; _i < _arr.length; _i++) {
        var key = _arr[_i];

        if (key[0] === '_') {
          delete t[key];
        }
      }

      if (withChildren && node.children) {
        t.children = node.children.slice();
        t.children.forEach(function (v, k) {
          t.children[k] = _this2.pure(v, withChildren);
        });
      }

      if (after) {
        return after(t, node) || t;
      }

      return t;
    }

function pure ( node , withChildren , after ) { var _this2 = this ; var t = assign$1 ( { } , node ) ; delete t . _id ; delete t . parent ; delete t . children ; delete t . open ; delete t . active ; delete t . style ; delete t . class ; delete t . innerStyle ; delete t . innerClass ; delete t . innerBackStyle ; delete t . innerBackClass ; var _arr = keys$1 ( t ) ; for ( var _i = 0 ; _i < _arr . length ; _i ++ ) { var key = _arr [ _i ] ; if ( key [ 0 ] === '_' ) { delete t [ key ] ; } } if ( withChildren && node . children ) { t . children = node . children . slice ( ) ; t . children . forEach ( function ( v , k ) { t . children [ k ] = _this2 . pure ( v , withChildren ) ; } ) ; } if ( after ) { return after ( t , node ) || t ; } return t ; }


function offset2() {
      return {
        x: this.offset.x + this.nodeInnerEl.offsetWidth,
        y: this.offset.y + this.nodeInnerEl.offsetHeight
      };
    }

function offset2 ( ) { return { x : this . offset . x + this . nodeInnerEl . offsetWidth , y : this . offset . y + this . nodeInnerEl . offsetHeight } ; }


function offsetToViewPort() {
      var r = this.nodeInnerEl.getBoundingClientRect();
      r.x = r.left;
      r.y = r.top;
      return r;
    }

function offsetToViewPort ( ) { var r = this . nodeInnerEl . getBoundingClientRect ( ) ; r . x = r . left ; r . y = r . top ; return r ; }


function currentTreeRootSecondChildExcludingDragging() {
      var _this = this;

      return this.currentTree.rootData.children.slice(0, 3).filter(function (v) {
        return v !== _this.node;
      })[1];
    }

the second child of currentTree root, excluding dragging node

the second child of currentTree root excluding dragging node


function appendPrev(info) {
    if (isNodeDroppable(info.targetPrev)) {
      th.appendTo(info.dplh, info.targetPrev);
      if (!info.targetPrev.open) info.store.toggleOpen(info.targetPrev);
    } else {
      insertDplhAfterTo(info.dplh, info.targetPrev, info);
    }
  }

function appendPrev ( info ) { if ( isNodeDroppable ( info . targetPrev ) ) { th . appendTo ( info . dplh , info . targetPrev ) ; if ( ! info . targetPrev . open ) info . store . toggleOpen ( info . targetPrev ) ; } else { insertDplhAfterTo ( info . dplh , info . targetPrev , info ) ; } }


function appendCurrentTree(info) {
    if (isNodeDroppable(info.currentTree.rootData)) {
      th.appendTo(info.dplh, info.currentTree.rootData);
    }
  }

function appendCurrentTree ( info ) { if ( isNodeDroppable ( info . currentTree . rootData ) ) { th . appendTo ( info . dplh , info . currentTree . rootData ) ; } }


function stripViewFromSelector (selector) {
    // Don't strip it out if it's one of these 4 element types
    // (see https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBElementTypeTransformer.m for reference)
    const keepView = [
      'XCUIElementTypeScrollView',
      'XCUIElementTypeCollectionView',
      'XCUIElementTypeTextView',
      'XCUIElementTypeWebView',
    ].includes(selector);

    if (!keepView && selector.indexOf('View') === selector.length - 4) {
      return selector.substr(0, selector.length - 4);
    } else {
      return selector;
    }
  }

function stripViewFromSelector ( selector ) { const keepView = [ 'XCUIElementTypeScrollView' , 'XCUIElementTypeCollectionView' , 'XCUIElementTypeTextView' , 'XCUIElementTypeWebView' , ] . includes ( selector ) ; if ( ! keepView && selector . indexOf ( 'View' ) === selector . length - 4 ) { return selector . substr ( 0 , selector . length - 4 ) ; } else { return selector ; } }

Check if the word 'View' is appended to selector and if it is, strip it out

Check if the word View is appended to selector and if it is strip it out


async function getPidUsingPattern (pgrepPattern) {
  const args = ['-nif', pgrepPattern];
  try {
    const {stdout} = await exec('pgrep', args);
    const pid = parseInt(stdout, 10);
    if (isNaN(pid)) {
      log.debug(`Cannot parse process id from 'pgrep ${args.join(' ')}' output: ${stdout}`);
      return null;
    }
    return `${pid}`;
  } catch (err) {
    log.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);
    return null;
  }
}

async
function
getPidUsingPattern
(
pgrepPattern
)
{
const
args
=
[
'-nif'
,
pgrepPattern
]
;
try
{
const
{
stdout
}
=
await
exec
(
'pgrep'
,
args
)
;
const
pid
=
parseInt
(
stdout
,
10
)
;
if
(
isNaN
(
pid
)
)
{
log
.
debug
(
`
${
args
.
join
(
' '
)
}
${
stdout
}
`
)
;
return
;
}
return
`
${
pid
}
`
;
}
catch
(
err
)
{
log
.
debug
(
`
${
args
.
join
(
' '
)
}
${
err
.
code
}
`
)
;
return
;
}
}

Get the process id of the most recent running application
having the particular command line pattern.

@param {string} pgrepPattern - pgrep-compatible search pattern.
@return {string} Either a process id or null if no matches were found.

Get the process id of the most recent running application having the particular command line pattern .


async function killAppUsingPattern (pgrepPattern) {
  for (const signal of [2, 15, 9]) {
    if (!await getPidUsingPattern(pgrepPattern)) {
      return;
    }
    const args = [`-${signal}`, '-if', pgrepPattern];
    try {
      await exec('pkill', args);
    } catch (err) {
      log.debug(`pkill ${args.join(' ')} -> ${err.message}`);
    }
    await B.delay(100);
  }
}

async
function
killAppUsingPattern
(
pgrepPattern
)
{
for
(
const
signal
of
[
2
,
15
,
9
]
)
{
if
(
!
await
getPidUsingPattern
(
pgrepPattern
)
)
{
return
;
}
const
args
=
[
`
${
signal
}
`
,
'-if'
,
pgrepPattern
]
;
try
{
await
exec
(
'pkill'
,
args
)
;
}
catch
(
err
)
{
log
.
debug
(
`
${
args
.
join
(
' '
)
}
${
err
.
message
}
`
)
;
}
await
B
.
delay
(
100
)
;
}
}

Kill a process having the particular command line pattern.
This method tries to send SIGINT, SIGTERM and SIGKILL to the
matched processes in this order if the process is still running.

@param {string} pgrepPattern - pgrep-compatible search pattern.

Kill a process having the particular command line pattern . This method tries to send SIGINT SIGTERM and SIGKILL to the matched processes in this order if the process is still running .


async function getPIDsListeningOnPort (port, filteringFunc = null) {
  const result = [];
  try {
    // This only works since Mac OS X El Capitan
    const {stdout} = await exec('lsof', ['-ti', `tcp:${port}`]);
    result.push(...(stdout.trim().split(/\n+/)));
  } catch (e) {
    return result;
  }

  if (!_.isFunction(filteringFunc)) {
    return result;
  }
  return await B.filter(result, async (x) => {
    const {stdout} = await exec('ps', ['-p', x, '-o', 'command']);
    return await filteringFunc(stdout);
  });
}

async function getPIDsListeningOnPort ( port , filteringFunc = null ) { const result = [ ] ; try { const { stdout } = await exec ( 'lsof' , [ '-ti' , ` ${ port } ` ] ) ; result . push ( ... ( stdout . trim ( ) . split ( / \n+ / ) ) ) ; } catch ( e ) { return result ; } if ( ! _ . isFunction ( filteringFunc ) ) { return result ; } return await B . filter ( result , async ( x ) => { const { stdout } = await exec ( 'ps' , [ '-p' , x , '-o' , 'command' ] ) ; return await filteringFunc ( stdout ) ; } ) ; }

Get the IDs of processes listening on the particular system port.
It is also possible to apply additional filtering based on the
process command line.

@param {string|number} port - The port number.
@param {?Function} filteringFunc - Optional lambda function, which
receives command line string of the particular process
listening on given port, and is expected to return
either true or false to include/exclude the corresponding PID
from the resulting array.
@returns {Array<string>} - the list of matched process ids.

Get the IDs of processes listening on the particular system port . It is also possible to apply additional filtering based on the process command line .


async function removeAllSessionWebSocketHandlers (server, sessionId) {
  if (!server || !_.isFunction(server.getWebSocketHandlers)) {
    return;
  }

  const activeHandlers = await server.getWebSocketHandlers(sessionId);
  for (const pathname of _.keys(activeHandlers)) {
    await server.removeWebSocketHandler(pathname);
  }
}

async function removeAllSessionWebSocketHandlers ( server , sessionId ) { if ( ! server || ! _ . isFunction ( server . getWebSocketHandlers ) ) { return ; } const activeHandlers = await server . getWebSocketHandlers ( sessionId ) ; for ( const pathname of _ . keys ( activeHandlers ) ) { await server . removeWebSocketHandler ( pathname ) ; } }

Stops and removes all web socket handlers that are listening
in scope of the currect session.

@param {Object} server - The instance of NodeJs HTTP server,
which hosts Appium
@param {string} sessionId - The id of the current session

Stops and removes all web socket handlers that are listening in scope of the currect session .


async function verifyApplicationPlatform (app, isSimulator) {
  log.debug('Verifying application platform');

  const infoPlist = path.resolve(app, 'Info.plist');
  if (!await fs.exists(infoPlist)) {
    log.debug(`'${infoPlist}' does not exist`);
    return null;
  }

  const {CFBundleSupportedPlatforms} = await plist.parsePlistFile(infoPlist);
  log.debug(`CFBundleSupportedPlatforms: ${JSON.stringify(CFBundleSupportedPlatforms)}`);
  if (!_.isArray(CFBundleSupportedPlatforms)) {
    log.debug(`CFBundleSupportedPlatforms key does not exist in '${infoPlist}'`);
    return null;
  }

  const isAppSupported = (isSimulator && CFBundleSupportedPlatforms.includes('iPhoneSimulator'))
    || (!isSimulator && CFBundleSupportedPlatforms.includes('iPhoneOS'));
  if (isAppSupported) {
    return true;
  }
  throw new Error(`${isSimulator ? 'Simulator' : 'Real device'} architecture is unsupported by the '${app}' application. ` +
                  `Make sure the correct deployment target has been selected for its compilation in Xcode.`);
}

async
function
verifyApplicationPlatform
(
app
,
isSimulator
)
{
log
.
debug
(
'Verifying application platform'
)
;
const
infoPlist
=
path
.
resolve
(
app
,
'Info.plist'
)
;
if
(
!
await
fs
.
exists
(
infoPlist
)
)
{
log
.
debug
(
`
${
infoPlist
}
`
)
;
return
;
}
const
{
CFBundleSupportedPlatforms
}
=
await
plist
.
parsePlistFile
(
infoPlist
)
;
log
.
debug
(
`
${
JSON
.
stringify
(
CFBundleSupportedPlatforms
)
}
`
)
;
if
(
!
_
.
isArray
(
CFBundleSupportedPlatforms
)
)
{
log
.
debug
(
`
${
infoPlist
}
`
)
;
return
;
}
const
isAppSupported
=
(
isSimulator
&&
CFBundleSupportedPlatforms
.
includes
(
'iPhoneSimulator'
)
)
||
(
!
isSimulator
&&
CFBundleSupportedPlatforms
.
includes
(
'iPhoneOS'
)
)
;
if
(
isAppSupported
)
{
return
true
;
}
throw
new
Error
(
`
${
isSimulator
'Simulator'
:
'Real device'
}
${
app
}
`
+
`
`
)
;
}

Verify whether the given application is compatible to the
platform where it is going to be installed and tested.

@param {string} app - The actual path to the application bundle
@param {boolean} isSimulator - Should be set to `true` if the test will be executed on Simulator
@returns {?boolean} The function returns `null` if the application does not exist or there is no
`CFBundleSupportedPlatforms` key in its Info.plist manifest.
`true` is returned if the bundle architecture matches the device architecture.
@throws {Error} If bundle architecture does not match the device architecture.

Verify whether the given application is compatible to the platform where it is going to be installed and tested .


function isLocalHost (urlString) {
  try {
    const {hostname} = url.parse(urlString);
    return ['localhost', '127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(hostname);
  } catch {
    log.warn(`'${urlString}' cannot be parsed as a valid URL`);
  }
  return false;
}

function isLocalHost ( urlString ) { try { const { hostname } = url . parse ( urlString ) ; return [ 'localhost' , '127.0.0.1' , '::1' , '::ffff:127.0.0.1' ] . includes ( hostname ) ; } catch { log . warn ( ` ${ urlString } ` ) ; } return false ; }

Returns true if the urlString is localhost
@param {?string} urlString
@returns {boolean} Return true if the urlString is localhost


function normalizePlatformVersion (originalVersion) {
  const normalizedVersion = util.coerceVersion(originalVersion, false);
  if (!normalizedVersion) {
    throw new Error(`The platform version '${originalVersion}' should be a valid version number`);
  }
  const {major, minor} = new semver.SemVer(normalizedVersion);
  return `${major}.${minor}`;
}

function normalizePlatformVersion ( originalVersion ) { const normalizedVersion = util . coerceVersion ( originalVersion , false ) ; if ( ! normalizedVersion ) { throw new Error ( ` ${ originalVersion } ` ) ; } const { major , minor } = new semver . SemVer ( normalizedVersion ) ; return ` ${ major } ${ minor } ` ; }

Normalizes platformVersion to a valid iOS version string

@param {string} originalVersion - Loose version number, that can be parsed by semver
@return {string} iOS version number in <major>.<minor> format
@throws {Error} if the version number cannot be parsed


async function updateProjectFile (agentPath, newBundleId) {
  let projectFilePath = `${agentPath}/${PROJECT_FILE}`;
  try {
    // Assuming projectFilePath is in the correct state, create .old from projectFilePath
    await fs.copyFile(projectFilePath, `${projectFilePath}.old`);
    await replaceInFile(projectFilePath, new RegExp(WDA_RUNNER_BUNDLE_ID.replace('.', '\.'), 'g'), newBundleId); // eslint-disable-line no-useless-escape
    log.debug(`Successfully updated '${projectFilePath}' with bundle id '${newBundleId}'`);
  } catch (err) {
    log.debug(`Error updating project file: ${err.message}`);
    log.warn(`Unable to update project file '${projectFilePath}' with ` +
             `bundle id '${newBundleId}'. WebDriverAgent may not start`);
  }
}

async function updateProjectFile ( agentPath , newBundleId ) { let projectFilePath = ` ${ agentPath } ${ PROJECT_FILE } ` ; try { await fs . copyFile ( projectFilePath , ` ${ projectFilePath } ` ) ; await replaceInFile ( projectFilePath , new RegExp ( WDA_RUNNER_BUNDLE_ID . replace ( '.' , '\.' ) , \. ) , 'g' ) ; newBundleId } log . debug ( ` ${ projectFilePath } ${ newBundleId } ` ) ; }

Update WebDriverAgentRunner project bundle ID with newBundleId.
This method assumes project file is in the correct state.
@param {string} agentPath - Path to the .xcodeproj directory.
@param {string} newBundleId the new bundle ID used to update.

Update WebDriverAgentRunner project bundle ID with newBundleId . This method assumes project file is in the correct state .


async function resetProjectFile (agentPath) {
  let projectFilePath = `${agentPath}/${PROJECT_FILE}`;
  try {
    // restore projectFilePath from .old file
    if (!await fs.exists(`${projectFilePath}.old`)) {
      return; // no need to reset
    }
    await fs.mv(`${projectFilePath}.old`, projectFilePath);
    log.debug(`Successfully reset '${projectFilePath}' with bundle id '${WDA_RUNNER_BUNDLE_ID}'`);
  } catch (err) {
    log.debug(`Error resetting project file: ${err.message}`);
    log.warn(`Unable to reset project file '${projectFilePath}' with ` +
             `bundle id '${WDA_RUNNER_BUNDLE_ID}'. WebDriverAgent has been ` +
             `modified and not returned to the original state.`);
  }
}

async function resetProjectFile ( agentPath ) { let projectFilePath = ` ${ agentPath } ${ PROJECT_FILE } ` ; try { if ( ! await fs . exists ( ` ${ projectFilePath } ` ) ) { return ; } await fs . mv ( ` ${ projectFilePath } ` , projectFilePath ) ; log . debug ( ` ${ projectFilePath } ${ WDA_RUNNER_BUNDLE_ID } ` ) ; } catch ( err ) { log . debug ( ` ${ err . message } ` ) ; log . warn ( ` ${ projectFilePath } ` + ` ${ WDA_RUNNER_BUNDLE_ID } ` + ` ` ) ; } }

Reset WebDriverAgentRunner project bundle ID to correct state.
@param {string} agentPath - Path to the .xcodeproj directory.

Reset WebDriverAgentRunner project bundle ID to correct state .


function getAdditionalRunContent (platformName, wdaRemotePort) {
  const runner = `WebDriverAgentRunner${isTvOS(platformName) ? '_tvOS' : ''}`;

  return {
    [runner]: {
      EnvironmentVariables: {
        USE_PORT: wdaRemotePort
      }
    }
  };
}

function getAdditionalRunContent ( platformName , wdaRemotePort ) { const runner = ` ${ isTvOS ( platformName ) ? '_tvOS' : '' } ` ; return { [ runner ] : { EnvironmentVariables : { USE_PORT : wdaRemotePort } } } ; }

Return the WDA object which appends existing xctest runner content
@param {string} platformName - The name of the platform
@param {string} version - The Xcode SDK version of OS.
@return {object} returns a runner object which has USE_PORT


async function getWDAUpgradeTimestamp (bootstrapPath) {
  const carthageRootPath = path.resolve(bootstrapPath, CARTHAGE_ROOT);
  if (await fs.exists(carthageRootPath)) {
    const {mtime} = await fs.stat(carthageRootPath);
    return mtime.getTime();
  }
  return null;
}

async function getWDAUpgradeTimestamp ( bootstrapPath ) { const carthageRootPath = path . resolve ( bootstrapPath , CARTHAGE_ROOT ) ; if ( await fs . exists ( carthageRootPath ) ) { const { mtime } = await fs . stat ( carthageRootPath ) ; return mtime . getTime ( ) ; } return null ; }

Retrieves WDA upgrade timestamp

@param {string} bootstrapPath The full path to the folder where WDA source is located
@return {?number} The UNIX timestamp of the carthage root folder, where dependencies are downloaded.
This folder is created only once on module upgrade/first install.


async function parseContainerPath (remotePath, containerRootSupplier) {
  const match = CONTAINER_PATH_PATTERN.exec(remotePath);
  if (!match) {
    log.errorAndThrow(`It is expected that package identifier ` +
      `starts with '${CONTAINER_PATH_MARKER}' and is separated from the ` +
      `relative path with a single slash. '${remotePath}' is given instead`);
  }
  let [, bundleId, relativePath] = match;
  let containerType = null;
  const typeSeparatorPos = bundleId.indexOf(CONTAINER_TYPE_SEPARATOR);
  // We only consider container type exists if its length is greater than zero
  // not counting the colon
  if (typeSeparatorPos > 0 && typeSeparatorPos < bundleId.length - 1) {
    containerType = bundleId.substring(typeSeparatorPos + 1);
    log.debug(`Parsed container type: ${containerType}`);
    bundleId = bundleId.substring(0, typeSeparatorPos);
  }
  const containerRoot = _.isFunction(containerRootSupplier)
    ? await containerRootSupplier(bundleId, containerType)
    : containerRootSupplier;
  const resultPath = path.posix.resolve(containerRoot, relativePath);
  verifyIsSubPath(resultPath, containerRoot);
  return [bundleId, resultPath];
}

async function parseContainerPath ( remotePath , containerRootSupplier ) { const match = CONTAINER_PATH_PATTERN . exec ( remotePath ) ; if ( ! match ) { log . errorAndThrow ( ` ` + ` ${ CONTAINER_PATH_MARKER } ` + ` ${ remotePath } ` ) ; } let [ , bundleId , relativePath ] = match ; let containerType = null ; const typeSeparatorPos = bundleId . indexOf ( CONTAINER_TYPE_SEPARATOR ) ; if ( typeSeparatorPos > 0 && typeSeparatorPos < bundleId . length - 1 ) { containerType = bundleId . substring ( typeSeparatorPos + 1 ) ; log . debug ( ` ${ containerType } ` ) ; bundleId = bundleId . substring ( 0 , typeSeparatorPos ) ; } const containerRoot = _ . isFunction ( containerRootSupplier ) ? await containerRootSupplier ( bundleId , containerType ) : containerRootSupplier ; const resultPath = path . posix . resolve ( containerRoot , relativePath ) ; verifyIsSubPath ( resultPath , containerRoot ) ; return [ bundleId , resultPath ] ; }

Parses the actual path and the bundle identifier from the given path string

@param {string} remotePath - The given path string. The string should
match `CONTAINER_PATH_PATTERN` regexp, otherwise an error is going
to be thrown. A valid string example: `@bundle.identifier:container_type/relative_path_in_container`
@param {Function|string} containerRootSupplier - Either a string, that contains
full path to the mount root for real devices or a function, which accepts two parameters
(bundle identifier and optional container type) and returns full path to container
root folder on the local file system, for Simulator
@returns {Array<string>} - An array where the first item is the parsed bundle
identifier and the second one is the absolute full path of the item on the local
file system


async function pushFileToSimulator (device, remotePath, base64Data) {
  const buffer = Buffer.from(base64Data, 'base64');
  if (CONTAINER_PATH_PATTERN.test(remotePath)) {
    const [bundleId, dstPath] = await parseContainerPath(remotePath,
      async (appBundle, containerType) => await getAppContainer(device.udid, appBundle, null, containerType));
    log.info(`Parsed bundle identifier '${bundleId}' from '${remotePath}'. ` +
      `Will put the data into '${dstPath}'`);
    if (!await fs.exists(path.dirname(dstPath))) {
      log.debug(`The destination folder '${path.dirname(dstPath)}' does not exist. Creating...`);
      await mkdirp(path.dirname(dstPath));
    }
    await fs.writeFile(dstPath, buffer);
    return;
  }
  const dstFolder = await tempDir.openDir();
  const dstPath = path.resolve(dstFolder, path.basename(remotePath));
  try {
    await fs.writeFile(dstPath, buffer);
    await addMedia(device.udid, dstPath);
  } finally {
    await fs.rimraf(dstFolder);
  }
}

async function pushFileToSimulator ( device , remotePath , base64Data ) { const buffer = Buffer . from ( base64Data , 'base64' ) ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , dstPath ] = await parseContainerPath ( remotePath , async ( appBundle , containerType ) => await getAppContainer ( device . udid , appBundle , null , containerType ) ) ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; if ( ! await fs . exists ( path . dirname ( dstPath ) ) ) { log . debug ( ` ${ path . dirname ( dstPath ) } ` ) ; await mkdirp ( path . dirname ( dstPath ) ) ; } await fs . writeFile ( dstPath , buffer ) ; return ; } const dstFolder = await tempDir . openDir ( ) ; const dstPath = path . resolve ( dstFolder , path . basename ( remotePath ) ) ; try { await fs . writeFile ( dstPath , buffer ) ; await addMedia ( device . udid , dstPath ) ; } finally { await fs . rimraf ( dstFolder ) ; } }

Save the given base64 data chunk as a binary file on the Simulator under test.

@param {Object} device - The device object, which represents the device under test.
This object is expected to have the `udid` property containing the
valid device ID.
@param {string} remotePath - The remote path on the device. This variable can be prefixed with
bundle id, so then the file will be uploaded to the corresponding
application container instead of the default media folder, for example
'@com.myapp.bla:data/RelativePathInContainer/111.png'. The '@' character at the
beginning of the argument is mandatory in such case. The colon at the end of bundle identifier
is optional and is used to distinguish the container type.
Possible values there are 'app', 'data', 'groups', '<A specific App Group container>'.
The default value is 'app'.
The relative folder path is ignored if the file is going to be uploaded
to the default media folder and only the file name is considered important.
@param {string} base64Data - Base-64 encoded content of the file to be uploaded.

Save the given base64 data chunk as a binary file on the Simulator under test .


async function pullFromSimulator (device, remotePath, isFile) {
  let pathOnServer;
  if (CONTAINER_PATH_PATTERN.test(remotePath)) {
    const [bundleId, dstPath] = await parseContainerPath(remotePath,
      async (appBundle, containerType) => await getAppContainer(device.udid, appBundle, null, containerType));
    log.info(`Parsed bundle identifier '${bundleId}' from '${remotePath}'. ` +
      `Will get the data from '${dstPath}'`);
    pathOnServer = dstPath;
  } else {
    const simRoot = device.getDir();
    pathOnServer = path.posix.join(simRoot, remotePath);
    verifyIsSubPath(pathOnServer, simRoot);
    log.info(`Got the full item path: ${pathOnServer}`);
  }
  if (!await fs.exists(pathOnServer)) {
    log.errorAndThrow(`The remote ${isFile ? 'file' : 'folder'} at '${pathOnServer}' does not exist`);
  }
  const buffer = isFile
    ? await fs.readFile(pathOnServer)
    : await zip.toInMemoryZip(pathOnServer);
  return Buffer.from(buffer).toString('base64');
}

async function pullFromSimulator ( device , remotePath , isFile ) { let pathOnServer ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , dstPath ] = await parseContainerPath ( remotePath , async ( appBundle , containerType ) => await getAppContainer ( device . udid , appBundle , null , containerType ) ) ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; pathOnServer = dstPath ; } else { const simRoot = device . getDir ( ) ; pathOnServer = path . posix . join ( simRoot , remotePath ) ; verifyIsSubPath ( pathOnServer , simRoot ) ; log . info ( ` ${ pathOnServer } ` ) ; } if ( ! await fs . exists ( pathOnServer ) ) { log . errorAndThrow ( ` ${ isFile ? 'file' : 'folder' } ${ pathOnServer } ` ) ; } const buffer = isFile ? await fs . readFile ( pathOnServer ) : await zip . toInMemoryZip ( pathOnServer ) ; return Buffer . from ( buffer ) . toString ( 'base64' ) ; }

Get the content of given file or folder from iOS Simulator and return it as base-64 encoded string.
Folder content is recursively packed into a zip archive.

@param {Object} device - The device object, which represents the device under test.
This object is expected to have the `udid` property containing the
valid device ID.
@param {string} remotePath - The path to a file or a folder, which exists in the corresponding application
container on Simulator. Use
@<app_bundle_id>:<optional_container_type>/<path_to_the_file_or_folder_inside_container>
format to pull a file or a folder from an application container of the given type.
Possible container types are 'app', 'data', 'groups', '<A specific App Group container>'.
The default type is 'app'.
@param {boolean} isFile - Whether the destination item is a file or a folder
@returns {string} Base-64 encoded content of the file.

Get the content of given file or folder from iOS Simulator and return it as base - 64 encoded string . Folder content is recursively packed into a zip archive .


async function pullFromRealDevice (device, remotePath, isFile) {
  await verifyIFusePresence();
  const mntRoot = await tempDir.openDir();
  let isUnmountSuccessful = true;
  try {
    let dstPath = path.resolve(mntRoot, remotePath);
    let ifuseArgs = ['-u', device.udid, mntRoot];
    if (CONTAINER_PATH_PATTERN.test(remotePath)) {
      const [bundleId, pathInContainer] = await parseContainerPath(remotePath, mntRoot);
      dstPath = pathInContainer;
      log.info(`Parsed bundle identifier '${bundleId}' from '${remotePath}'. ` +
        `Will get the data from '${dstPath}'`);
      ifuseArgs = ['-u', device.udid, '--container', bundleId, mntRoot];
    } else {
      verifyIsSubPath(dstPath, mntRoot);
    }
    await mountDevice(device, ifuseArgs);
    isUnmountSuccessful = false;
    try {
      if (!await fs.exists(dstPath)) {
        log.errorAndThrow(`The remote ${isFile ? 'file' : 'folder'} at '${dstPath}' does not exist`);
      }
      const buffer = isFile
        ? await fs.readFile(dstPath)
        : await zip.toInMemoryZip(dstPath);
      return Buffer.from(buffer).toString('base64');
    } finally {
      await exec('umount', [mntRoot]);
      isUnmountSuccessful = true;
    }
  } finally {
    if (isUnmountSuccessful) {
      await fs.rimraf(mntRoot);
    } else {
      log.warn(`Umount has failed, so not removing '${mntRoot}'`);
    }
  }
}

async function pullFromRealDevice ( device , remotePath , isFile ) { await verifyIFusePresence ( ) ; const mntRoot = await tempDir . openDir ( ) ; let isUnmountSuccessful = true ; try { let dstPath = path . resolve ( mntRoot , remotePath ) ; let ifuseArgs = [ '-u' , device . udid , mntRoot ] ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , pathInContainer ] = await parseContainerPath ( remotePath , mntRoot ) ; dstPath = pathInContainer ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; ifuseArgs = [ '-u' , device . udid , '--container' , bundleId , mntRoot ] ; } else { verifyIsSubPath ( dstPath , mntRoot ) ; } await mountDevice ( device , ifuseArgs ) ; isUnmountSuccessful = false ; try { if ( ! await fs . exists ( dstPath ) ) { log . errorAndThrow ( ` ${ isFile ? 'file' : 'folder' } ${ dstPath } ` ) ; } const buffer = isFile ? await fs . readFile ( dstPath ) : await zip . toInMemoryZip ( dstPath ) ; return Buffer . from ( buffer ) . toString ( 'base64' ) ; } finally { await exec ( 'umount' , [ mntRoot ] ) ; isUnmountSuccessful = true ; } } finally { if ( isUnmountSuccessful ) { await fs . rimraf ( mntRoot ) ; } else { log . warn ( ` ${ mntRoot } ` ) ; } } }

Get the content of given file or folder from the real device under test and return it as base-64 encoded string.
Folder content is recursively packed into a zip archive.

@param {Object} device - The device object, which represents the device under test.
This object is expected to have the `udid` property containing the
valid device ID.
@param {string} remotePath - The path to an existing remote file on the device. This variable can be prefixed with
bundle id, so then the file will be downloaded from the corresponding
application container instead of the default media folder, for example
'@com.myapp.bla/RelativePathInContainer/111.png'. The '@' character at the
beginning of the argument is mandatory in such case.
@param {boolean} isFile - Whether the destination item is a file or a folder
@return {string} Base-64 encoded content of the remote file

Get the content of given file or folder from the real device under test and return it as base - 64 encoded string . Folder content is recursively packed into a zip archive .


async function createSim (caps, platform = PLATFORM_NAME_IOS) {
  const appiumTestDeviceName = `appiumTest-${UUID.create().toString().toUpperCase()}-${caps.deviceName}`;
  const udid = await createDevice(
    appiumTestDeviceName,
    caps.deviceName,
    caps.platformVersion,
    { platform }
  );
  return await getSimulator(udid);
}

async function createSim ( caps , platform = PLATFORM_NAME_IOS ) { const appiumTestDeviceName = ` ${ UUID . create ( ) . toString ( ) . toUpperCase ( ) } ${ caps . deviceName } ` ; const udid = await createDevice ( appiumTestDeviceName , caps . deviceName , caps . platformVersion , { platform } ) ; return await getSimulator ( udid ) ; }

Capability set by a user

@property {string} deviceName - A name for the device
@property {string} platformVersion - The version of iOS to use

Create a new simulator with `appiumTest-` prefix and return the object.

@param {object} SimCreationCaps - Capability set by a user. The options available are:
@property {string} platform [iOS] - Platform name in order to specify runtime such as 'iOS', 'tvOS', 'watchOS'
@returns {object} Simulator object associated with the udid passed in.


async function getExistingSim (opts) {
  const devices = await getDevices(opts.platformVersion);
  const appiumTestDeviceName = `appiumTest-${opts.deviceName}`;

  let appiumTestDevice;

  for (const device of _.values(devices)) {
    if (device.name === opts.deviceName) {
      return await getSimulator(device.udid);
    }

    if (device.name === appiumTestDeviceName) {
      appiumTestDevice = device;
    }
  }

  if (appiumTestDevice) {
    log.warn(`Unable to find device '${opts.deviceName}'. Found '${appiumTestDevice.name}' (udid: '${appiumTestDevice.udid}') instead`);
    return await getSimulator(appiumTestDevice.udid);
  }
  return null;
}

async function getExistingSim ( opts ) { const devices = await getDevices ( opts . platformVersion ) ; const appiumTestDeviceName = ` ${ opts . deviceName } ` ; let appiumTestDevice ; for ( const device of _ . values ( devices ) ) { if ( device . name === opts . deviceName ) { return await getSimulator ( device . udid ) ; } if ( device . name === appiumTestDeviceName ) { appiumTestDevice = device ; } } if ( appiumTestDevice ) { log . warn ( ` ${ opts . deviceName } ${ appiumTestDevice . name } ${ appiumTestDevice . udid } ` ) ; return await getSimulator ( appiumTestDevice . udid ) ; } return null ; }

Get a simulator which is already running.

@param {object} opts - Capability set by a user. The options available are:
- `deviceName` - a name for the device
- `platformVersion` - the version of iOS to use
@returns {?object} Simulator object associated with the udid passed in. Or null if no device is running.

Get a simulator which is already running .


function () {
    const data = this.data;
    let objectEls;

    // Push entities into list of els to intersect.
    if (data.objects) {
      objectEls = this.el.sceneEl.querySelectorAll(data.objects);
    } else {
      // If objects not defined, intersect with everything.
      objectEls = this.el.sceneEl.children;
    }
    // Convert from NodeList to Array
    this.els = Array.prototype.slice.call(objectEls);
  }

function ( ) { const data = this . data ; let objectEls ; if ( data . objects ) { objectEls = this . el . sceneEl . querySelectorAll ( data . objects ) ; } else { objectEls = this . el . sceneEl . children ; } this . els = Array . prototype . slice . call ( objectEls ) ; }

Update list of entities to test for collision.

Update list of entities to test for collision .


function intersect (el) {
        let radius, mesh, distance, extent;

        if (!el.isEntity) { return; }

        mesh = el.getObject3D('mesh');

        if (!mesh) { return; }

        box.setFromObject(mesh).getSize(size);
        extent = Math.max(size.x, size.y, size.z) / 2;
        radius = Math.sqrt(2 * extent * extent);
        box.getCenter(meshPosition);

        if (!radius) { return; }

        distance = position.distanceTo(meshPosition);
        if (distance < radius + colliderRadius) {
          collisions.push(el);
          distanceMap.set(el, distance);
        }
      }

function intersect ( el ) { let radius , mesh , distance , extent ; if ( ! el . isEntity ) { return ; } mesh = el . getObject3D ( 'mesh' ) ; if ( ! mesh ) { return ; } box . setFromObject ( mesh ) . getSize ( size ) ; extent = Math . max ( size . x , size . y , size . z ) / 2 ; radius = Math . sqrt ( 2 * extent * extent ) ; box . getCenter ( meshPosition ) ; if ( ! radius ) { return ; } distance = position . distanceTo ( meshPosition ) ; if ( distance < radius + colliderRadius ) { collisions . push ( el ) ; distanceMap . set ( el , distance ) ; } }


function () {
    const gamepad = this.getGamepad();
    if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
      return new THREE.Vector2();
    }
    return new THREE.Vector2(
      (gamepad.buttons[GamepadButton.DPAD_RIGHT].pressed ? 1 : 0)
      + (gamepad.buttons[GamepadButton.DPAD_LEFT].pressed ? -1 : 0),
      (gamepad.buttons[GamepadButton.DPAD_UP].pressed ? -1 : 0)
      + (gamepad.buttons[GamepadButton.DPAD_DOWN].pressed ? 1 : 0)
    );
  }

function ( ) { const gamepad = this . getGamepad ( ) ; if ( ! gamepad . buttons [ GamepadButton . DPAD_RIGHT ] ) { return new THREE . Vector2 ( ) ; } return new THREE . Vector2 ( ( gamepad . buttons [ GamepadButton . DPAD_RIGHT ] . pressed ? 1 : 0 ) + ( gamepad . buttons [ GamepadButton . DPAD_LEFT ] . pressed ? - 1 : 0 ) , ( gamepad . buttons [ GamepadButton . DPAD_UP ] . pressed ? - 1 : 0 ) + ( gamepad . buttons [ GamepadButton . DPAD_DOWN ] . pressed ? 1 : 0 ) ) ; }

Returns the state of the dpad as a THREE.Vector2.
@return {THREE.Vector2}

Returns the state of the dpad as a THREE . Vector2 .


function URLSearchParamsPolyfill(search) {
        search = search || "";

        // support construct object with another URLSearchParams instance
        if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {
            search = search.toString();
        }
        this [__URLSearchParams__] = parseToDict(search);
    }

function URLSearchParamsPolyfill ( search ) { search = search || "" ; if ( search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill ) { search = search . toString ( ) ; } this [ __URLSearchParams__ ] = parseToDict ( search ) ; }

Make a URLSearchParams instance

@param {object|string|URLSearchParams} search
@constructor


function RequestQueue(opts) {
  if (!opts || typeof (opts) !== 'object') {
    opts = {};
  }
  this.size = (opts.size > 0) ? opts.size : Infinity;
  this.timeout = (opts.timeout > 0) ? opts.timeout : 0;
  this._queue = [];
  this._timer = null;
  this._frozen = false;
}

function RequestQueue ( opts ) { if ( ! opts || typeof ( opts ) !== 'object' ) { opts = { } ; } this . size = ( opts . size > 0 ) ? opts . size : Infinity ; this . timeout = ( opts . timeout > 0 ) ? opts . timeout : 0 ; this . _queue = [ ] ; this . _timer = null ; this . _frozen = false ; }

Queue to contain LDAP requests.

@param {Object} opts queue options

Accepted Options:
- size: Maximum queue size
- timeout: Set timeout between first queue insertion and queue flush.


function MessageTracker(opts) {
  assert.object(opts);
  assert.string(opts.id);
  assert.object(opts.parser);

  this.id = opts.id;
  this._msgid = 0;
  this._messages = {};
  this._abandoned = {};
  this.parser = opts.parser;

  var self = this;
  this.__defineGetter__('pending', function () {
    return Object.keys(self._messages);
  });
}

function MessageTracker ( opts ) { assert . object ( opts ) ; assert . string ( opts . id ) ; assert . object ( opts . parser ) ; this . id = opts . id ; this . _msgid = 0 ; this . _messages = { } ; this . _abandoned = { } ; this . parser = opts . parser ; var self = this ; this . __defineGetter__ ( 'pending' , function ( ) { return Object . keys ( self . _messages ) ; } ) ; }


function connectSocket(cb) {
    cb = once(cb);

    function onResult(err, res) {
      if (err) {
        if (self.connectTimer) {
          clearTimeout(self.connectTimer);
          self.connectTimer = null;
        }
        self.emit('connectError', err);
      }
      cb(err, res);
    }
    function onConnect() {
      if (self.connectTimer) {
        clearTimeout(self.connectTimer);
        self.connectTimer = null;
      }
      socket.removeAllListeners('error')
        .removeAllListeners('connect')
        .removeAllListeners('secureConnect');

      tracker.id = nextClientId() + '__' + tracker.id;
      self.log = self.log.child({ldap_id: tracker.id}, true);

      // Move on to client setup
      setupClient(cb);
    }

    var port = (self.port || self.socketPath);
    if (self.secure) {
      socket = tls.connect(port, self.host, self.tlsOptions);
      socket.once('secureConnect', onConnect);
    } else {
      socket = net.connect(port, self.host);
      socket.once('connect', onConnect);
    }
    socket.once('error', onResult);
    initSocket();

    // Setup connection timeout handling, if desired
    if (self.connectTimeout) {
      self.connectTimer = setTimeout(function onConnectTimeout() {
        if (!socket || !socket.readable || !socket.writeable) {
          socket.destroy();
          self._socket = null;
          onResult(new ConnectionError('connection timeout'));
        }
      }, self.connectTimeout);
    }
  }

function
connectSocket
(
cb
)
{
cb
=
once
(
cb
)
;
function
onResult
(
err
,
res
)
{
if
(
err
)
{
if
(
self
.
connectTimer
)
{
clearTimeout
(
self
.
connectTimer
)
;
self
.
connectTimer
=
;
}
self
.
emit
(
'connectError'
,
err
)
;
}
cb
(
err
,
res
)
;
}
function
onConnect
(
)
{
if
(
self
.
connectTimer
)
{
clearTimeout
(
self
.
connectTimer
)
;
self
.
connectTimer
=
;
}
socket
.
removeAllListeners
(
'error'
)
.
removeAllListeners
(
'connect'
)
.
removeAllListeners
(
'secureConnect'
)
;
tracker
.
id
=
nextClientId
(
)
+
'__'
+
tracker
.
id
;
self
.
log
=
self
.
log
.
child
(
{
ldap_id
:
tracker
.
id
}
,
true
)
;
setupClient
(
cb
)
;
}
var
port
=
(
self
.
port
||
self
.
socketPath
)
;
if
(
self
.
secure
)
{
socket
=
tls
.
connect
(
port
,
self
.
host
,
self
.
tlsOptions
)
;
socket
.
once
(
'secureConnect'
,
onConnect
)
;
}
else
{
socket
=
net
.
connect
(
port
,
self
.
host
)
;
socket
.
once
(
'connect'
,
onConnect
)
;
}
socket
.
once
(
'error'
,
onResult
)
;
initSocket
(
)
;
if
(
self
.
connectTimeout
)
{
self
.
connectTimer
=
setTimeout
(
function
onConnectTimeout
(
)
{
if
(
!
socket
||
!
socket
.
readable
||
!
socket
.
writeable
)
{
socket
.
destroy
(
)
;
self
.
_socket
=
;
onResult
(
new
ConnectionError
(
'connection timeout'
)
)
;
}
}
,
self
.
connectTimeout
)
;
}
}


function initSocket() {
    tracker = new MessageTracker({
      id: self.url ? self.url.href : self.socketPath,
      parser: new Parser({log: log})
    });

    // This won't be set on TLS. So. Very. Annoying.
    if (typeof (socket.setKeepAlive) !== 'function') {
      socket.setKeepAlive = function setKeepAlive(enable, delay) {
        return socket.socket ?
          socket.socket.setKeepAlive(enable, delay) : false;
      };
    }

    socket.on('data', function onData(data) {
      if (log.trace())
        log.trace('data event: %s', util.inspect(data));

      tracker.parser.write(data);
    });

    // The "router"
    tracker.parser.on('message', function onMessage(message) {
      message.connection = self._socket;
      var callback = tracker.fetch(message.messageID);

      if (!callback) {
        log.error({message: message.json}, 'unsolicited message');
        return false;
      }

      return callback(message);
    });

    tracker.parser.on('error', function onParseError(err) {
      self.emit('error', new VError(err, 'Parser error for %s',
            tracker.id));
      self.connected = false;
      socket.end();
    });
  }

function
initSocket
(
)
{
tracker
=
new
MessageTracker
(
{
id
:
self
.
url
self
.
url
.
href
:
self
.
socketPath
,
parser
:
new
Parser
(
{
log
:
log
}
)
}
)
;
if
(
typeof
(
socket
.
setKeepAlive
)
!==
'function'
)
{
socket
.
setKeepAlive
=
function
setKeepAlive
(
enable
,
delay
)
{
return
socket
.
socket
socket
.
socket
.
setKeepAlive
(
enable
,
delay
)
:
false
;
}
;
}
socket
.
on
(
'data'
,
function
onData
(
data
)
{
if
(
log
.
trace
(
)
)
log
.
trace
(
'data event: %s'
,
util
.
inspect
(
data
)
)
;
tracker
.
parser
.
write
(
data
)
;
}
)
;
tracker
.
parser
.
on
(
'message'
,
function
onMessage
(
message
)
{
message
.
connection
=
self
.
_socket
;
var
callback
=
tracker
.
fetch
(
message
.
messageID
)
;
if
(
!
callback
)
{
log
.
error
(
{
message
:
message
.
json
}
,
'unsolicited message'
)
;
return
false
;
}
return
callback
(
message
)
;
}
)
;
tracker
.
parser
.
on
(
'error'
,
function
onParseError
(
err
)
{
self
.
emit
(
'error'
,
new
VError
(
err
,
'Parser error for %s'
,
tracker
.
id
)
)
;
self
.
connected
=
false
;
socket
.
end
(
)
;
}
)
;
}

Initialize socket events and LDAP parser.

Initialize socket events and LDAP parser .


function setupClient(cb) {
    cb = once(cb);

    // Indicate failure if anything goes awry during setup
    function bail(err) {
      socket.destroy();
      cb(err || new Error('client error during setup'));
    }
    // Work around lack of close event on tls.socket in node < 0.11
    ((socket.socket) ? socket.socket : socket).once('close', bail);
    socket.once('error', bail);
    socket.once('end', bail);
    socket.once('timeout', bail);

    self._socket = socket;
    self._tracker = tracker;

    // Run any requested setup (such as automatically performing a bind) on
    // socket before signalling successful connection.
    // This setup needs to bypass the request queue since all other activity is
    // blocked until the connection is considered fully established post-setup.
    // Only allow bind/search/starttls for now.
    var basicClient = {
      bind: function bindBypass(name, credentials, controls, callback) {
        return self.bind(name, credentials, controls, callback, true);
      },
      search: function searchBypass(base, options, controls, callback) {
        return self.search(base, options, controls, callback, true);
      },
      starttls: function starttlsBypass(options, controls, callback) {
        return self.starttls(options, controls, callback, true);
      },
      unbind: self.unbind.bind(self)
    };
    vasync.forEachPipeline({
      func: function (f, callback) {
        f(basicClient, callback);
      },
      inputs: self.listeners('setup')
    }, function (err, res) {
      if (err) {
        self.emit('setupError', err);
      }
      cb(err);
    });
  }

function
setupClient
(
cb
)
{
cb
=
once
(
cb
)
;
function
bail
(
err
)
{
socket
.
destroy
(
)
;
cb
(
err
||
new
Error
(
'client error during setup'
)
)
;
}
(
(
socket
.
socket
)
socket
.
socket
:
socket
)
.
once
(
'close'
,
bail
)
;
socket
.
once
(
'error'
,
bail
)
;
socket
.
once
(
'end'
,
bail
)
;
socket
.
once
(
'timeout'
,
bail
)
;
self
.
_socket
=
socket
;
self
.
_tracker
=
tracker
;
var
basicClient
=
{
bind
:
function
bindBypass
(
name
,
credentials
,
controls
,
callback
)
{
return
self
.
bind
(
name
,
credentials
,
controls
,
callback
,
true
)
;
}
,
search
:
function
searchBypass
(
base
,
options
,
controls
,
callback
)
{
return
self
.
search
(
base
,
options
,
controls
,
callback
,
true
)
;
}
,
starttls
:
function
starttlsBypass
(
options
,
controls
,
callback
)
{
return
self
.
starttls
(
options
,
controls
,
callback
,
true
)
;
}
,
unbind
:
self
.
unbind
.
bind
(
self
)
}
;
vasync
.
forEachPipeline
(
{
func
:
function
(
f
,
callback
)
{
f
(
basicClient
,
callback
)
;
}
,
inputs
:
self
.
listeners
(
'setup'
)
}
,
function
(
err
,
res
)
{
if
(
err
)
{
self
.
emit
(
'setupError'
,
err
)
;
}
cb
(
err
)
;
}
)
;
}

After connect, register socket event handlers and run any setup actions

After connect register socket event handlers and run any setup actions


function Graph(gridIn, options) {
  options = options || {};
  this.nodes = [];
  this.diagonal = !!options.diagonal;
  this.grid = [];
  for (var x = 0; x < gridIn.length; x++) {
    this.grid[x] = [];

    for (var y = 0, row = gridIn[x]; y < row.length; y++) {
      var node = new GridNode(x, y, row[y]);
      this.grid[x][y] = node;
      this.nodes.push(node);
    }
  }
  this.init();
}

function Graph ( gridIn , options ) { options = options || { } ; this . nodes = [ ] ; this . diagonal = ! ! options . diagonal ; this . grid = [ ] ; for ( var x = 0 ; x < gridIn . length ; x ++ ) { this . grid [ x ] = [ ] ; for ( var y = 0 , row = gridIn [ x ] ; y < row . length ; y ++ ) { var node = new GridNode ( x , y , row [ y ] ) ; this . grid [ x ] [ y ] = node ; this . nodes . push ( node ) ; } } this . init ( ) ; }

A graph memory structure
@param {Array} gridIn 2D array of input weights
@param {Object} [options]
@param {bool} [options.diagonal] Specifies whether diagonal moves are allowed


function(path, i) {
        if(i >= path.length) { // finished removing path, set start positions
            return setStartClass(path, i);
        }
        elementFromNode(path[i]).removeClass(css.active);
        setTimeout(function() {
            removeClass(path, i+1);
        }, timeout*path[i].getCost());
    }

function ( path , i ) { if ( i >= path . length ) { return setStartClass ( path , i ) ; } elementFromNode ( path [ i ] ) . removeClass ( css . active ) ; setTimeout ( function ( ) { removeClass ( path , i + 1 ) ; } , timeout * path [ i ] . getCost ( ) ) ; }


function forEach(array, callback) {
        if (array) {
            for (var i = 0, len = array.length; i < len; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }

function forEach ( array , callback ) { if ( array ) { for ( var i = 0 , len = array . length ; i < len ; i ++ ) { var result = callback ( array [ i ] , i ) ; if ( result ) { return result ; } } } return undefined ; }

Iterates through 'array' by index and performs the callback on each element of array until the callback
returns a truthy value, then returns that value.
If no such value is found, the callback is applied to each element of array and undefined is returned.

Iterates through array by index and performs the callback on each element of array until the callback returns a truthy value then returns that value . If no such value is found the callback is applied to each element of array and undefined is returned .


function arrayToMap(array, makeKey) {
        var result = {};
        forEach(array, function (value) {
            result[makeKey(value)] = value;
        });
        return result;
    }

function arrayToMap ( array , makeKey ) { var result = { } ; forEach ( array , function ( value ) { result [ makeKey ( value ) ] = value ; } ) ; return result ; }

Creates a map from the elements of an array.

@param array the array of input elements.
@param makeKey a function that produces a key for a given element.

This function makes no effort to avoid collisions; if any two elements produce
the same key with the given 'makeKey' function, then the element with the higher
index in the array will be the one associated with the produced key.

Creates a map from the elements of an array .


function createWatchedFileSet(interval, chunkSize) {
                if (interval === void 0) { interval = 2500; }
                if (chunkSize === void 0) { chunkSize = 30; }
                var watchedFiles = [];
                var nextFileToCheck = 0;
                var watchTimer;
                function getModifiedTime(fileName) {
                    return _fs.statSync(fileName).mtime;
                }
                function poll(checkedIndex) {
                    var watchedFile = watchedFiles[checkedIndex];
                    if (!watchedFile) {
                        return;
                    }
                    _fs.stat(watchedFile.fileName, function (err, stats) {
                        if (err) {
                            watchedFile.callback(watchedFile.fileName);
                        }
                        else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
                            watchedFile.mtime = getModifiedTime(watchedFile.fileName);
                            watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0);
                        }
                    });
                }
                // this implementation uses polling and
                // stat due to inconsistencies of fs.watch
                // and efficiency of stat on modern filesystems
                function startWatchTimer() {
                    watchTimer = setInterval(function () {
                        var count = 0;
                        var nextToCheck = nextFileToCheck;
                        var firstCheck = -1;
                        while ((count < chunkSize) && (nextToCheck !== firstCheck)) {
                            poll(nextToCheck);
                            if (firstCheck < 0) {
                                firstCheck = nextToCheck;
                            }
                            nextToCheck++;
                            if (nextToCheck === watchedFiles.length) {
                                nextToCheck = 0;
                            }
                            count++;
                        }
                        nextFileToCheck = nextToCheck;
                    }, interval);
                }
                function addFile(fileName, callback) {
                    var file = {
                        fileName: fileName,
                        callback: callback,
                        mtime: getModifiedTime(fileName)
                    };
                    watchedFiles.push(file);
                    if (watchedFiles.length === 1) {
                        startWatchTimer();
                    }
                    return file;
                }
                function removeFile(file) {
                    watchedFiles = ts.copyListRemovingItem(file, watchedFiles);
                }
                return {
                    getModifiedTime: getModifiedTime,
                    poll: poll,
                    startWatchTimer: startWatchTimer,
                    addFile: addFile,
                    removeFile: removeFile
                };
            }

function createWatchedFileSet ( interval , chunkSize ) { if ( interval === void 0 ) { interval = 2500 ; } if ( chunkSize === void 0 ) { chunkSize = 30 ; } var watchedFiles = [ ] ; var nextFileToCheck = 0 ; var watchTimer ; function getModifiedTime ( fileName ) { return _fs . statSync ( fileName ) . mtime ; } function poll ( checkedIndex ) { var watchedFile = watchedFiles [ checkedIndex ] ; if ( ! watchedFile ) { return ; } _fs . stat ( watchedFile . fileName , function ( err , stats ) { if ( err ) { watchedFile . callback ( watchedFile . fileName ) ; } else if ( watchedFile . mtime . getTime ( ) !== stats . mtime . getTime ( ) ) { watchedFile . mtime = getModifiedTime ( watchedFile . fileName ) ; watchedFile . callback ( watchedFile . fileName , watchedFile . mtime . getTime ( ) === 0 ) ; } } ) ; } function startWatchTimer ( ) { watchTimer = setInterval ( function ( ) { var count = 0 ; var nextToCheck = nextFileToCheck ; var firstCheck = - 1 ; while ( ( count < chunkSize ) && ( nextToCheck !== firstCheck ) ) { poll ( nextToCheck ) ; if ( firstCheck < 0 ) { firstCheck = nextToCheck ; } nextToCheck ++ ; if ( nextToCheck === watchedFiles . length ) { nextToCheck = 0 ; } count ++ ; } nextFileToCheck = nextToCheck ; } , interval ) ; } function addFile ( fileName , callback ) { var file = { fileName : fileName , callback : callback , mtime : getModifiedTime ( fileName ) } ; watchedFiles . push ( file ) ; if ( watchedFiles . length === 1 ) { startWatchTimer ( ) ; } return file ; } function removeFile ( file ) { watchedFiles = ts . copyListRemovingItem ( file , watchedFiles ) ; } return { getModifiedTime : getModifiedTime , poll : poll , startWatchTimer : startWatchTimer , addFile : addFile , removeFile : removeFile } ; }

average async stat takes about 30 microseconds set chunk size to do 30 files in < 1 millisecond


function startWatchTimer() {
                    watchTimer = setInterval(function () {
                        var count = 0;
                        var nextToCheck = nextFileToCheck;
                        var firstCheck = -1;
                        while ((count < chunkSize) && (nextToCheck !== firstCheck)) {
                            poll(nextToCheck);
                            if (firstCheck < 0) {
                                firstCheck = nextToCheck;
                            }
                            nextToCheck++;
                            if (nextToCheck === watchedFiles.length) {
                                nextToCheck = 0;
                            }
                            count++;
                        }
                        nextFileToCheck = nextToCheck;
                    }, interval);
                }

function startWatchTimer ( ) { watchTimer = setInterval ( function ( ) { var count = 0 ; var nextToCheck = nextFileToCheck ; var firstCheck = - 1 ; while ( ( count < chunkSize ) && ( nextToCheck !== firstCheck ) ) { poll ( nextToCheck ) ; if ( firstCheck < 0 ) { firstCheck = nextToCheck ; } nextToCheck ++ ; if ( nextToCheck === watchedFiles . length ) { nextToCheck = 0 ; } count ++ ; } nextFileToCheck = nextToCheck ; } , interval ) ; }

this implementation uses polling and stat due to inconsistencies of fs.watch and efficiency of stat on modern filesystems

this implementation uses polling and stat due to inconsistencies of fs . watch and efficiency of stat on modern filesystems


function scanTemplateAndSetTokenValue() {
            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
            pos++;
            var start = pos;
            var contents = "";
            var resultingToken;
            while (true) {
                if (pos >= end) {
                    contents += text.substring(start, pos);
                    tokenIsUnterminated = true;
                    error(ts.Diagnostics.Unterminated_template_literal);
                    resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 12 /* TemplateHead */ : 13 /* TemplateMiddle */;
                    break;
                }
                // Escape character
                if (currChar === 92 /* backslash */) {
                    contents += text.substring(start, pos);
                    contents += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                // Speculated ECMAScript 6 Spec 11.8.6.1:
                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
                if (currChar === 13 /* carriageReturn */) {
                    contents += text.substring(start, pos);
                    pos++;
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                    contents += "\n";
                    start = pos;
                    continue;
                }
                pos++;
            }
            ts.Debug.assert(resultingToken !== undefined);
            tokenValue = contents;
            return resultingToken;
        }

function scanTemplateAndSetTokenValue ( ) { var startedWithBacktick = text . charCodeAt ( pos ) === 96 ; pos ++ ; var start = pos ; var contents = "" ; var resultingToken ; while ( true ) { if ( pos >= end ) { contents += text . substring ( start , pos ) ; tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_template_literal ) ; resultingToken = startedWithBacktick ? 11 : 14 ; break ; } var currChar = text . charCodeAt ( pos ) ; if ( currChar === 96 ) { contents += text . substring ( start , pos ) ; pos ++ ; resultingToken = startedWithBacktick ? 11 : 14 ; break ; } if ( currChar === 36 && pos + 1 < end && text . charCodeAt ( pos + 1 ) === 123 ) { contents += text . substring ( start , pos ) ; pos += 2 ; resultingToken = startedWithBacktick ? 12 : 13 ; break ; } if ( currChar === 92 ) { contents += text . substring ( start , pos ) ; contents += scanEscapeSequence ( ) ; start = pos ; continue ; } if ( currChar === 13 ) { contents += text . substring ( start , pos ) ; pos ++ ; if ( pos < end && text . charCodeAt ( pos ) === 10 ) { pos ++ ; } contents += "\n" ; \n start = pos ; } continue ; } pos ++ ; ts . Debug . assert ( resultingToken !== undefined ) ; tokenValue = contents ; }

Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
a literal component of a TemplateExpression.

Sets the current tokenValue and returns a NoSubstitutionTemplateLiteral or a literal component of a TemplateExpression .


function utf16EncodeAsString(codePoint) {
            ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
            if (codePoint <= 65535) {
                return String.fromCharCode(codePoint);
            }
            var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
            var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
            return String.fromCharCode(codeUnit1, codeUnit2);
        }

function utf16EncodeAsString ( codePoint ) { ts . Debug . assert ( 0x0 <= codePoint && codePoint <= 0x10FFFF ) ; if ( codePoint <= 65535 ) { return String . fromCharCode ( codePoint ) ; } var codeUnit1 = Math . floor ( ( codePoint - 65536 ) / 1024 ) + 0xD800 ; var codeUnit2 = ( ( codePoint - 65536 ) % 1024 ) + 0xDC00 ; return String . fromCharCode ( codeUnit1 , codeUnit2 ) ; }

Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.


function peekUnicodeEscape() {
            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
                var start_1 = pos;
                pos += 2;
                var value = scanExactNumberOfHexDigits(4);
                pos = start_1;
                return value;
            }
            return -1;
        }

function peekUnicodeEscape ( ) { if ( pos + 5 < end && text . charCodeAt ( pos + 1 ) === 117 ) { var start_1 = pos ; pos += 2 ; var value = scanExactNumberOfHexDigits ( 4 ) ; pos = start_1 ; return value ; } return - 1 ; }

Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' and return code point value if valid Unicode escape is found. Otherwise return -1.

Current character is known to be a backslash . Check for Unicode escape of the form \ uXXXX and return code point value if valid Unicode escape is found . Otherwise return - 1 .


function scanJsxIdentifier() {
            if (tokenIsIdentifierOrKeyword(token)) {
                var firstCharPosition = pos;
                while (pos < end) {
                    var ch = text.charCodeAt(pos);
                    if (ch === 45 /* minus */ || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) {
                        pos++;
                    }
                    else {
                        break;
                    }
                }
                tokenValue += text.substr(firstCharPosition, pos - firstCharPosition);
            }
            return token;
        }

function scanJsxIdentifier ( ) { if ( tokenIsIdentifierOrKeyword ( token ) ) { var firstCharPosition = pos ; while ( pos < end ) { var ch = text . charCodeAt ( pos ) ; if ( ch === 45 || ( ( firstCharPosition === pos ) ? isIdentifierStart ( ch , languageVersion ) : isIdentifierPart ( ch , languageVersion ) ) ) { pos ++ ; } else { break ; } } tokenValue += text . substr ( firstCharPosition , pos - firstCharPosition ) ; } return token ; }

Scans a JSX identifier; these differ from normal identifiers in that they allow dashes

Scans a JSX identifier ; these differ from normal identifiers in that they allow dashes


function getDeclarationName(node) {
            if (node.name) {
                if (node.kind === 218 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */) {
                    return "\"" + node.name.text + "\"";
                }
                if (node.name.kind === 136 /* ComputedPropertyName */) {
                    var nameExpression = node.name.expression;
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(nameExpression.name.text);
                }
                return node.name.text;
            }
            switch (node.kind) {
                case 144 /* Constructor */:
                    return "__constructor";
                case 152 /* FunctionType */:
                case 147 /* CallSignature */:
                    return "__call";
                case 153 /* ConstructorType */:
                case 148 /* ConstructSignature */:
                    return "__new";
                case 149 /* IndexSignature */:
                    return "__index";
                case 228 /* ExportDeclaration */:
                    return "__export";
                case 227 /* ExportAssignment */:
                    return node.isExportEquals ? "export=" : "default";
                case 213 /* FunctionDeclaration */:
                case 214 /* ClassDeclaration */:
                    return node.flags & 1024 /* Default */ ? "default" : undefined;
            }
        }

function getDeclarationName ( node ) { if ( node . name ) { if ( node . kind === 218 && node . name . kind === 9 ) { return "\"" + \" + node . name . text ; } "\"" \" } if ( node . name . kind === 136 ) { var nameExpression = node . name . expression ; ts . Debug . assert ( ts . isWellKnownSymbolSyntactically ( nameExpression ) ) ; return ts . getPropertyNameForKnownSymbolName ( nameExpression . name . text ) ; } }

Should not be called on a declaration with a computed property name, unless it is a well known Symbol.

Should not be called on a declaration with a computed property name unless it is a well known Symbol .


function bindChildren(node) {
            // Before we recurse into a node's chilren, we first save the existing parent, container
            // and block-container.  Then after we pop out of processing the children, we restore
            // these saved values.
            var saveParent = parent;
            var saveContainer = container;
            var savedBlockScopeContainer = blockScopeContainer;
            // This node will now be set as the parent of all of its children as we recurse into them.
            parent = node;
            // Depending on what kind of node this is, we may have to adjust the current container
            // and block-container.   If the current node is a container, then it is automatically
            // considered the current block-container as well.  Also, for containers that we know
            // may contain locals, we proactively initialize the .locals field. We do this because
            // it's highly likely that the .locals will be needed to place some child in (for example,
            // a parameter, or variable declaration).
            //
            // However, we do not proactively create the .locals for block-containers because it's
            // totally normal and common for block-containers to never actually have a block-scoped
            // variable in them.  We don't want to end up allocating an object for every 'block' we
            // run into when most of them won't be necessary.
            //
            // Finally, if this is a block-container, then we clear out any existing .locals object
            // it may contain within it.  This happens in incremental scenarios.  Because we can be
            // reusing a node from a previous compilation, that node may have had 'locals' created
            // for it.  We must clear this so we don't accidently move any stale data forward from
            // a previous compilation.
            var containerFlags = getContainerFlags(node);
            if (containerFlags & 1 /* IsContainer */) {
                container = blockScopeContainer = node;
                if (containerFlags & 4 /* HasLocals */) {
                    container.locals = {};
                }
                addToContainerChain(container);
            }
            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                blockScopeContainer = node;
                blockScopeContainer.locals = undefined;
            }
            if (node.kind === 215 /* InterfaceDeclaration */) {
                seenThisKeyword = false;
                ts.forEachChild(node, bind);
                node.flags = seenThisKeyword ? node.flags | 524288 /* ContainsThis */ : node.flags & ~524288 /* ContainsThis */;
            }
            else {
                ts.forEachChild(node, bind);
            }
            container = saveContainer;
            parent = saveParent;
            blockScopeContainer = savedBlockScopeContainer;
        }

function bindChildren ( node ) { var saveParent = parent ; var saveContainer = container ; var savedBlockScopeContainer = blockScopeContainer ; parent = node ; var containerFlags = getContainerFlags ( node ) ; if ( containerFlags & 1 ) { container = blockScopeContainer = node ; if ( containerFlags & 4 ) { container . locals = { } ; } addToContainerChain ( container ) ; } else if ( containerFlags & 2 ) { blockScopeContainer = node ; blockScopeContainer . locals = undefined ; } if ( node . kind === 215 ) { seenThisKeyword = false ; ts . forEachChild ( node , bind ) ; node . flags = seenThisKeyword ? node . flags | 524288 : node . flags & ~ 524288 ; } else { ts . forEachChild ( node , bind ) ; } container = saveContainer ; parent = saveParent ; blockScopeContainer = savedBlockScopeContainer ; }

All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function in the type checker to validate that the local name used for a container is unique.

All container nodes are kept on a linked list in declaration order . This list is used by the getLocalNameOfContainer function in the type checker to validate that the local name used for a container is unique .


function nodePosToString(node) {
        var file = getSourceFileOfNode(node);
        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
    }

function nodePosToString ( node ) { var file = getSourceFileOfNode ( node ) ; var loc = ts . getLineAndCharacterOfPosition ( file , node . pos ) ; return file . fileName + "(" + ( loc . line + 1 ) + "," + ( loc . character + 1 ) + ")" ; }

This is a useful function for debugging purposes.

This is a useful function for debugging purposes .


function unescapeIdentifier(identifier) {
        return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
    }

function unescapeIdentifier ( identifier ) { return identifier . length >= 3 && identifier . charCodeAt ( 0 ) === 95 && identifier . charCodeAt ( 1 ) === 95 && identifier . charCodeAt ( 2 ) === 95 ? identifier . substr ( 1 ) : identifier ; }

Remove extra underscore from escaped identifier


function getEnclosingBlockScopeContainer(node) {
        var current = node.parent;
        while (current) {
            if (isFunctionLike(current)) {
                return current;
            }
            switch (current.kind) {
                case 248 /* SourceFile */:
                case 220 /* CaseBlock */:
                case 244 /* CatchClause */:
                case 218 /* ModuleDeclaration */:
                case 199 /* ForStatement */:
                case 200 /* ForInStatement */:
                case 201 /* ForOfStatement */:
                    return current;
                case 192 /* Block */:
                    // function block is not considered block-scope container
                    // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                    if (!isFunctionLike(current.parent)) {
                        return current;
                    }
            }
            current = current.parent;
        }
    }

function getEnclosingBlockScopeContainer ( node ) { var current = node . parent ; while ( current ) { if ( isFunctionLike ( current ) ) { return current ; } switch ( current . kind ) { case 248 : case 220 : case 244 : case 218 : case 199 : case 200 : case 201 : return current ; case 192 : if ( ! isFunctionLike ( current . parent ) ) { return current ; } } current = current . parent ; } }

Gets the nearest enclosing block scope container that has the provided node as a descendant, that is not the provided node.

Gets the nearest enclosing block scope container that has the provided node as a descendant that is not the provided node .


function isDeclarationName(name) {
        if (name.kind !== 69 /* Identifier */ && name.kind !== 9 /* StringLiteral */ && name.kind !== 8 /* NumericLiteral */) {
            return false;
        }
        var parent = name.parent;
        if (parent.kind === 226 /* ImportSpecifier */ || parent.kind === 230 /* ExportSpecifier */) {
            if (parent.propertyName) {
                return true;
            }
        }
        if (isDeclaration(parent)) {
            return parent.name === name;
        }
        return false;
    }

function isDeclarationName ( name ) { if ( name . kind !== 69 && name . kind !== 9 && name . kind !== 8 ) { return false ; } var parent = name . parent ; if ( parent . kind === 226 || parent . kind === 230 ) { if ( parent . propertyName ) { return true ; } } if ( isDeclaration ( parent ) ) { return parent . name === name ; } return false ; }

True if the given identifier, string literal, or number literal is the name of a declaration node

True if the given identifier string literal or number literal is the name of a declaration node


function isIdentifierName(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 141 /* PropertyDeclaration */:
            case 140 /* PropertySignature */:
            case 143 /* MethodDeclaration */:
            case 142 /* MethodSignature */:
            case 145 /* GetAccessor */:
            case 146 /* SetAccessor */:
            case 247 /* EnumMember */:
            case 245 /* PropertyAssignment */:
            case 166 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 135 /* QualifiedName */:
                // Name on right hand side of dot in a type query
                if (parent.right === node) {
                    while (parent.kind === 135 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 154 /* TypeQuery */;
                }
                return false;
            case 163 /* BindingElement */:
            case 226 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 230 /* ExportSpecifier */:
                // Any name in an export specifier
                return true;
        }
        return false;
    }

function isIdentifierName ( node ) { var parent = node . parent ; switch ( parent . kind ) { case 141 : case 140 : case 143 : case 142 : case 145 : case 146 : case 247 : case 245 : case 166 : return parent . name === node ; case 135 : if ( parent . right === node ) { while ( parent . kind === 135 ) { parent = parent . parent ; } return parent . kind === 154 ; } return false ; case 163 : case 226 : return parent . propertyName === node ; case 230 : return true ; } return false ; }

Return true if the given identifier is classified as an IdentifierName


function getExpandedCharCodes(input) {
        var output = [];
        var length = input.length;
        for (var i = 0; i < length; i++) {
            var charCode = input.charCodeAt(i);
            // handel utf8
            if (charCode < 0x80) {
                output.push(charCode);
            }
            else if (charCode < 0x800) {
                output.push((charCode >> 6) | 192);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x10000) {
                output.push((charCode >> 12) | 224);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x20000) {
                output.push((charCode >> 18) | 240);
                output.push(((charCode >> 12) & 63) | 128);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else {
                ts.Debug.assert(false, "Unexpected code point");
            }
        }
        return output;
    }

function
getExpandedCharCodes
(
input
)
{
var
output
=
[
]
;
var
length
=
input
.
length
;
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
var
charCode
=
input
.
charCodeAt
(
i
)
;
if
(
charCode
<
0x80
)
{
output
.
push
(
charCode
)
;
}
else
if
(
charCode
<
0x800
)
{
output
.
push
(
(
charCode
>>
6
)
|
192
)
;
output
.
push
(
(
charCode
&
63
)
|
128
)
;
}
else
if
(
charCode
<
0x10000
)
{
output
.
push
(
(
charCode
>>
12
)
|
224
)
;
output
.
push
(
(
(
charCode
>>
6
)
&
63
)
|
128
)
;
output
.
push
(
(
charCode
&
63
)
|
128
)
;
}
else
if
(
charCode
<
0x20000
)
{
output
.
push
(
(
charCode
>>
18
)
|
240
)
;
output
.
push
(
(
(
charCode
>>
12
)
&
63
)
|
128
)
;
output
.
push
(
(
(
charCode
>>
6
)
&
63
)
|
128
)
;
output
.
push
(
(
charCode
&
63
)
|
128
)
;
}
else
{
ts
.
Debug
.
assert
(
false
,
"Unexpected code point"
)
;
}
}
return
output
;
}

Replace each instance of non-ascii characters by one, two, three, or four escape sequences
representing the UTF-8 encoding of the character, and return the expanded char code list.

Replace each instance of non - ascii characters by one two three or four escape sequences representing the UTF - 8 encoding of the character and return the expanded char code list .


function textSpanContainsTextSpan(span, other) {
        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
    }

function textSpanContainsTextSpan ( span , other ) { return other . start >= span . start && textSpanEnd ( other ) <= textSpanEnd ( span ) ; }

Returns true if 'span' contains 'other'.


function isListTerminator(kind) {
            if (token === 1 /* EndOfFileToken */) {
                // Being at the end of the file ends all lists.
                return true;
            }
            switch (kind) {
                case 1 /* BlockStatements */:
                case 2 /* SwitchClauses */:
                case 4 /* TypeMembers */:
                case 5 /* ClassMembers */:
                case 6 /* EnumMembers */:
                case 12 /* ObjectLiteralMembers */:
                case 9 /* ObjectBindingElements */:
                case 21 /* ImportOrExportSpecifiers */:
                    return token === 16 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token === 16 /* CloseBraceToken */ || token === 71 /* CaseKeyword */ || token === 77 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token === 15 /* OpenBraceToken */ || token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 17 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token === 27 /* GreaterThanToken */ || token === 17 /* OpenParenToken */ || token === 15 /* OpenBraceToken */ || token === 83 /* ExtendsKeyword */ || token === 106 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token === 18 /* CloseParenToken */ || token === 23 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 19 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token === 20 /* CloseBracketToken */;
                case 16 /* Parameters */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token === 18 /* CloseParenToken */ || token === 20 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 18 /* TypeArguments */:
                    // Tokens other than '>' are here for better error recovery
                    return token === 27 /* GreaterThanToken */ || token === 17 /* OpenParenToken */;
                case 20 /* HeritageClauses */:
                    return token === 15 /* OpenBraceToken */ || token === 16 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token === 27 /* GreaterThanToken */ || token === 39 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token === 25 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
                case 22 /* JSDocFunctionParameters */:
                    return token === 18 /* CloseParenToken */ || token === 54 /* ColonToken */ || token === 16 /* CloseBraceToken */;
                case 23 /* JSDocTypeArguments */:
                    return token === 27 /* GreaterThanToken */ || token === 16 /* CloseBraceToken */;
                case 25 /* JSDocTupleTypes */:
                    return token === 20 /* CloseBracketToken */ || token === 16 /* CloseBraceToken */;
                case 24 /* JSDocRecordMembers */:
                    return token === 16 /* CloseBraceToken */;
            }
        }

function isListTerminator ( kind ) { if ( token === 1 ) { return true ; } switch ( kind ) { case 1 : case 2 : case 4 : case 5 : case 6 : case 12 : case 9 : case 21 : return token === 16 ; case 3 : return token === 16 || token === 71 || token === 77 ; case 7 : return token === 15 || token === 83 || token === 106 ; case 8 : return isVariableDeclaratorListTerminator ( ) ; case 17 : return token === 27 || token === 17 || token === 15 || token === 83 || token === 106 ; case 11 : return token === 18 || token === 23 ; case 15 : case 19 : case 10 : return token === 20 ; case 16 : return token === 18 || token === 20 ; case 18 : return token === 27 || token === 17 ; case 20 : return token === 15 || token === 16 ; case 13 : return token === 27 || token === 39 ; case 14 : return token === 25 && lookAhead ( nextTokenIsSlash ) ; case 22 : return token === 18 || token === 54 || token === 16 ; case 23 : return token === 27 || token === 16 ; case 25 : return token === 20 || token === 16 ; case 24 : return token === 16 ; } }


function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = parseIdentifier(diagnosticMessage);
            while (parseOptional(21 /* DotToken */)) {
                var node = createNode(135 /* QualifiedName */, entity.pos);
                node.left = entity;
                node.right = parseRightSideOfDot(allowReservedWords);
                entity = finishNode(node);
            }
            return entity;
        }

function parseEntityName ( allowReservedWords , diagnosticMessage ) { var entity = parseIdentifier ( diagnosticMessage ) ; while ( parseOptional ( 21 ) ) { var node = createNode ( 135 , entity . pos ) ; node . left = entity ; node . right = parseRightSideOfDot ( allowReservedWords ) ; entity = finishNode ( node ) ; } return entity ; }

The allowReservedWords parameter controls whether reserved words are permitted after the first dot


function findHighestListElementThatStartsAtPosition(position) {
                // Clear out any cached state about the last node we found.
                currentArray = undefined;
                currentArrayIndex = -1 /* Value */;
                current = undefined;
                // Recurse into the source file to find the highest node at this position.
                forEachChild(sourceFile, visitNode, visitArray);
                return;
                function visitNode(node) {
                    if (position >= node.pos && position < node.end) {
                        // Position was within this node.  Keep searching deeper to find the node.
                        forEachChild(node, visitNode, visitArray);
                        // don't procede any futher in the search.
                        return true;
                    }
                    // position wasn't in this node, have to keep searching.
                    return false;
                }
                function visitArray(array) {
                    if (position >= array.pos && position < array.end) {
                        // position was in this array.  Search through this array to see if we find a
                        // viable element.
                        for (var i = 0, n = array.length; i < n; i++) {
                            var child = array[i];
                            if (child) {
                                if (child.pos === position) {
                                    // Found the right node.  We're done.
                                    currentArray = array;
                                    currentArrayIndex = i;
                                    current = child;
                                    return true;
                                }
                                else {
                                    if (child.pos < position && position < child.end) {
                                        // Position in somewhere within this child.  Search in it and
                                        // stop searching in this array.
                                        forEachChild(child, visitNode, visitArray);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    // position wasn't in this array, have to keep searching.
                    return false;
                }
            }

Finds the highest element in the tree we can find that starts at the provided position. The element must be a direct child of some node list in the tree.  This way after we return it, we can easily return its next sibling in the list.

Finds the highest element in the tree we can find that starts at the provided position . The element must be a direct child of some node list in the tree . This way after we return it we can easily return its next sibling in the list .


function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, importDeclaration) {
            if (!importDeclaration) {
                importDeclaration = ts.getAncestor(entityName, 221 /* ImportEqualsDeclaration */);
                ts.Debug.assert(importDeclaration !== undefined);
            }
            // There are three things we might try to look for. In the following examples,
            // the search term is enclosed in |...|:
            //
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (entityName.kind === 69 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 69 /* Identifier */ || entityName.parent.kind === 135 /* QualifiedName */) {
                return resolveEntityName(entityName, 1536 /* Namespace */);
            }
            else {
                // Case 2 in above example
                // entityName.kind could be a QualifiedName or a Missing identifier
                ts.Debug.assert(entityName.parent.kind === 221 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 107455 /* Value */ | 793056 /* Type */ | 1536 /* Namespace */);
            }
        }

This function is only for imports with entity names


function resolveEntityName(name, meaning, ignoreErrors) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var symbol;
            if (name.kind === 69 /* Identifier */) {
                var message = meaning === 1536 /* Namespace */ ? ts.Diagnostics.Cannot_find_namespace_0 : ts.Diagnostics.Cannot_find_name_0;
                symbol = resolveName(name, name.text, meaning, ignoreErrors ? undefined : message, name);
                if (!symbol) {
                    return undefined;
                }
            }
            else if (name.kind === 135 /* QualifiedName */ || name.kind === 166 /* PropertyAccessExpression */) {
                var left = name.kind === 135 /* QualifiedName */ ? name.left : name.expression;
                var right = name.kind === 135 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, 1536 /* Namespace */, ignoreErrors);
                if (!namespace || namespace === unknownSymbol || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                symbol = getSymbol(getExportsOfSymbol(namespace), right.text, meaning);
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else {
                ts.Debug.fail("Unknown entity name kind.");
            }
            ts.Debug.assert((symbol.flags & 16777216 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
            return symbol.flags & meaning ? symbol : resolveAlias(symbol);
        }

Resolves a qualified name and any involved aliases


function isReservedMemberName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) !== 95 /* _ */ &&
                name.charCodeAt(2) !== 64 /* at */;
        }

function isReservedMemberName ( name ) { return name . charCodeAt ( 0 ) === 95 && name . charCodeAt ( 1 ) === 95 && name . charCodeAt ( 2 ) !== 95 && name . charCodeAt ( 2 ) !== 64 ; }

A reserved member name starts with two underscores, but the third character cannot be an underscore or the @ symbol. A third underscore indicates an escaped form of an identifer that started with at least two underscores. The @ character indicates that the name is denoted by a well known ES Symbol instance.

A reserved member name starts with two underscores but the third character cannot be an underscore or the


function isSymbolUsedInExportAssignment(symbol) {
                    if (exportAssignmentSymbol === symbol) {
                        return true;
                    }
                    if (exportAssignmentSymbol && !!(exportAssignmentSymbol.flags & 8388608 /* Alias */)) {
                        // if export assigned symbol is alias declaration, resolve the alias
                        resolvedExportSymbol = resolvedExportSymbol || resolveAlias(exportAssignmentSymbol);
                        if (resolvedExportSymbol === symbol) {
                            return true;
                        }
                        // Container of resolvedExportSymbol is visible
                        return ts.forEach(resolvedExportSymbol.declarations, function (current) {
                            while (current) {
                                if (current === node) {
                                    return true;
                                }
                                current = current.parent;
                            }
                        });
                    }
                }

function isSymbolUsedInExportAssignment ( symbol ) { if ( exportAssignmentSymbol === symbol ) { return true ; } if ( exportAssignmentSymbol && ! ! ( exportAssignmentSymbol . flags & 8388608 ) ) { resolvedExportSymbol = resolvedExportSymbol || resolveAlias ( exportAssignmentSymbol ) ; if ( resolvedExportSymbol === symbol ) { return true ; } return ts . forEach ( resolvedExportSymbol . declarations , function ( current ) { while ( current ) { if ( current === node ) { return true ; } current = current . parent ; } } ) ; } }

Check if the symbol is used in export assignment


function getTypeOfPropertyOfType(type, name) {
            var prop = getPropertyOfType(type, name);
            return prop ? getTypeOfSymbol(prop) : undefined;
        }

function getTypeOfPropertyOfType ( type , name ) { var prop = getPropertyOfType ( type , name ) ; return prop ? getTypeOfSymbol ( prop ) : undefined ; }

Return the type of the given property in the given type, or undefined if no such property exists

Return the type of the given property in the given type or undefined if no such property exists


function getTypeForBindingElementParent(node) {
            var symbol = getSymbolOfNode(node);
            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
        }

function getTypeForBindingElementParent ( node ) { var symbol = getSymbolOfNode ( node ) ; return symbol && getSymbolLinks ( symbol ) . type || getTypeForVariableLikeDeclaration ( node ) ; }

Return the type of a binding element parent. We check SymbolLinks first to see if a type has been assigned by contextual typing.

Return the type of a binding element parent . We check SymbolLinks first to see if a type has been assigned by contextual typing .


function getTypeForBindingElement(declaration) {
            var pattern = declaration.parent;
            var parentType = getTypeForBindingElementParent(pattern.parent);
            // If parent has the unknown (error) type, then so does this binding element
            if (parentType === unknownType) {
                return unknownType;
            }
            // If no type was specified or inferred for parent, or if the specified or inferred type is any,
            // infer from the initializer of the binding element if one is present. Otherwise, go with the
            // undefined or any type of the parent.
            if (!parentType || isTypeAny(parentType)) {
                if (declaration.initializer) {
                    return checkExpressionCached(declaration.initializer);
                }
                return parentType;
            }
            var type;
            if (pattern.kind === 161 /* ObjectBindingPattern */) {
                // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                var name_10 = declaration.propertyName || declaration.name;
                // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
                // or otherwise the type of the string index signature.
                type = getTypeOfPropertyOfType(parentType, name_10.text) ||
                    isNumericLiteralName(name_10.text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
                    getIndexTypeOfType(parentType, 0 /* String */);
                if (!type) {
                    error(name_10, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_10));
                    return unknownType;
                }
            }
            else {
                // This elementType will be used if the specific property corresponding to this index is not
                // present (aka the tuple element property). This call also checks that the parentType is in
                // fact an iterable or array (depending on target language).
                var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false);
                if (!declaration.dotDotDotToken) {
                    // Use specific property type when parent is a tuple or numeric index type when parent is an array
                    var propName = "" + ts.indexOf(pattern.elements, declaration);
                    type = isTupleLikeType(parentType)
                        ? getTypeOfPropertyOfType(parentType, propName)
                        : elementType;
                    if (!type) {
                        if (isTupleType(parentType)) {
                            error(declaration, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), parentType.elementTypes.length, pattern.elements.length);
                        }
                        else {
                            error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
                        }
                        return unknownType;
                    }
                }
                else {
                    // Rest element has an array type with the same element type as the parent type
                    type = createArrayType(elementType);
                }
            }
            return type;
        }

Return the inferred type for a binding element