function makeTempVariableName(flags) {
                if (flags && !(tempFlags & flags)) {
                    var name_19 = flags === 268435456 /* _i */ ? "_i" : "_n";
                    if (isUniqueName(name_19)) {
                        tempFlags |= flags;
                        return name_19;
                    }
                }
                while (true) {
                    var count = tempFlags & 268435455 /* CountMask */;
                    tempFlags++;
                    // Skip over 'i' and 'n'
                    if (count !== 8 && count !== 13) {
                        var name_20 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26);
                        if (isUniqueName(name_20)) {
                            return name_20;
                        }
                    }
                }
            }

function makeTempVariableName ( flags ) { if ( flags && ! ( tempFlags & flags ) ) { var name_19 = flags === 268435456 ? "_i" : "_n" ; if ( isUniqueName ( name_19 ) ) { tempFlags |= flags ; return name_19 ; } } while ( true ) { var count = tempFlags & 268435455 ; tempFlags ++ ; if ( count !== 8 && count !== 13 ) { var name_20 = count < 26 ? "_" + String . fromCharCode ( 97 + count ) : "_" + ( count - 26 ) ; if ( isUniqueName ( name_20 ) ) { return name_20 ; } } } }

Return the next available name in the pattern _a ... _z, _0, _1, ... TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. Note that names generated by makeTempVariableName and makeUniqueName will never conflict.

Return the next available name in the pattern _a ... _z _0 _1 ... TempFlags . _i or TempFlags . _n may be used to express a preference for that dedicated name . Note that names generated by makeTempVariableName and makeUniqueName will never conflict .


function makeUniqueName(baseName) {
                // Find the first unique 'name_n', where n is a positive number
                if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
                    baseName += "_";
                }
                var i = 1;
                while (true) {
                    var generatedName = baseName + i;
                    if (isUniqueName(generatedName)) {
                        return generatedNameSet[generatedName] = generatedName;
                    }
                    i++;
                }
            }

function makeUniqueName ( baseName ) { if ( baseName . charCodeAt ( baseName . length - 1 ) !== 95 ) { baseName += "_" ; } var i = 1 ; while ( true ) { var generatedName = baseName + i ; if ( isUniqueName ( generatedName ) ) { return generatedNameSet [ generatedName ] = generatedName ; } i ++ ; } }

Generate a name that is unique within the current file and doesn't conflict with any names in global scope. The name is formed by adding an '_n' suffix to the specified base name, where n is a positive integer. Note that names generated by makeTempVariableName and makeUniqueName are guaranteed to never conflict.

Generate a name that is unique within the current file and doesn t conflict with any names in global scope . The name is formed by adding an _n suffix to the specified base name where n is a positive integer . Note that names generated by makeTempVariableName and makeUniqueName are guaranteed to never conflict .


function encodeLastRecordedSourceMapSpan() {
                    if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
                        return;
                    }
                    var prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
                    // Line/Comma delimiters
                    if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
                        // Emit comma to separate the entry
                        if (sourceMapData.sourceMapMappings) {
                            sourceMapData.sourceMapMappings += ",";
                        }
                    }
                    else {
                        // Emit line delimiters
                        for (var encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
                            sourceMapData.sourceMapMappings += ";";
                        }
                        prevEncodedEmittedColumn = 1;
                    }
                    // 1. Relative Column 0 based
                    sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
                    // 2. Relative sourceIndex
                    sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
                    // 3. Relative sourceLine 0 based
                    sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
                    // 4. Relative sourceColumn 0 based
                    sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
                    // 5. Relative namePosition 0 based
                    if (lastRecordedSourceMapSpan.nameIndex >= 0) {
                        sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
                        lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
                    }
                    lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
                    sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
                    function base64VLQFormatEncode(inValue) {
                        function base64FormatEncode(inValue) {
                            if (inValue < 64) {
                                return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(inValue);
                            }
                            throw TypeError(inValue + ": not a 64 based value");
                        }
                        // Add a new least significant bit that has the sign of the value.
                        // if negative number the least significant bit that gets added to the number has value 1
                        // else least significant bit value that gets added is 0
                        // eg. -1 changes to binary : 01 [1] => 3
                        //     +1 changes to binary : 01 [0] => 2
                        if (inValue < 0) {
                            inValue = ((-inValue) << 1) + 1;
                        }
                        else {
                            inValue = inValue << 1;
                        }
                        // Encode 5 bits at a time starting from least significant bits
                        var encodedStr = "";
                        do {
                            var currentDigit = inValue & 31; // 11111
                            inValue = inValue >> 5;
                            if (inValue > 0) {
                                // There are still more digits to decode, set the msb (6th bit)
                                currentDigit = currentDigit | 32;
                            }
                            encodedStr = encodedStr + base64FormatEncode(currentDigit);
                        } while (inValue > 0);
                        return encodedStr;
                    }
                }


function createTempVariable(flags) {
                var result = ts.createSynthesizedNode(69 /* Identifier */);
                result.text = makeTempVariableName(flags);
                return result;
            }

function createTempVariable ( flags ) { var result = ts . createSynthesizedNode ( 69 ) ; result . text = makeTempVariableName ( flags ) ; return result ; }

Create a temporary variable with a unique unused name.

Create a temporary variable with a unique unused name .


function indentIfOnDifferentLines(parent, node1, node2, valueToWriteWhenNotIndenting) {
                var realNodesAreOnDifferentLines = !ts.nodeIsSynthesized(parent) && !nodeEndIsOnSameLineAsNodeStart(node1, node2);
                // Always use a newline for synthesized code if the synthesizer desires it.
                var synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2);
                if (realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine) {
                    increaseIndent();
                    writeLine();
                    return true;
                }
                else {
                    if (valueToWriteWhenNotIndenting) {
                        write(valueToWriteWhenNotIndenting);
                    }
                    return false;
                }
            }

function indentIfOnDifferentLines ( parent , node1 , node2 , valueToWriteWhenNotIndenting ) { var realNodesAreOnDifferentLines = ! ts . nodeIsSynthesized ( parent ) && ! nodeEndIsOnSameLineAsNodeStart ( node1 , node2 ) ; var synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine ( node2 ) ; if ( realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine ) { increaseIndent ( ) ; writeLine ( ) ; return true ; } else { if ( valueToWriteWhenNotIndenting ) { write ( valueToWriteWhenNotIndenting ) ; } return false ; } }

Returns 'true' if the code was actually indented, false otherwise. If the code is not indented, an optional valueToWriteWhenNotIndenting will be emitted instead.

Returns true if the code was actually indented false otherwise . If the code is not indented an optional valueToWriteWhenNotIndenting will be emitted instead .


function emitExponentiationOperator(node) {
                var leftHandSideExpression = node.left;
                if (node.operatorToken.kind === 60 /* AsteriskAsteriskEqualsToken */) {
                    var synthesizedLHS;
                    var shouldEmitParentheses = false;
                    if (ts.isElementAccessExpression(leftHandSideExpression)) {
                        shouldEmitParentheses = true;
                        write("(");
                        synthesizedLHS = ts.createSynthesizedNode(167 /* ElementAccessExpression */, /*startsOnNewLine*/ false);
                        var identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefinedTempVariablesInPlaces*/ false, /*shouldEmitCommaBeforeAssignment*/ false);
                        synthesizedLHS.expression = identifier;
                        if (leftHandSideExpression.argumentExpression.kind !== 8 /* NumericLiteral */ &&
                            leftHandSideExpression.argumentExpression.kind !== 9 /* StringLiteral */) {
                            var tempArgumentExpression = createAndRecordTempVariable(268435456 /* _i */);
                            synthesizedLHS.argumentExpression = tempArgumentExpression;
                            emitAssignment(tempArgumentExpression, leftHandSideExpression.argumentExpression, /*shouldEmitCommaBeforeAssignment*/ true);
                        }
                        else {
                            synthesizedLHS.argumentExpression = leftHandSideExpression.argumentExpression;
                        }
                        write(", ");
                    }
                    else if (ts.isPropertyAccessExpression(leftHandSideExpression)) {
                        shouldEmitParentheses = true;
                        write("(");
                        synthesizedLHS = ts.createSynthesizedNode(166 /* PropertyAccessExpression */, /*startsOnNewLine*/ false);
                        var identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefinedTempVariablesInPlaces*/ false, /*shouldemitCommaBeforeAssignment*/ false);
                        synthesizedLHS.expression = identifier;
                        synthesizedLHS.dotToken = leftHandSideExpression.dotToken;
                        synthesizedLHS.name = leftHandSideExpression.name;
                        write(", ");
                    }
                    emit(synthesizedLHS || leftHandSideExpression);
                    write(" = ");
                    write("Math.pow(");
                    emit(synthesizedLHS || leftHandSideExpression);
                    write(", ");
                    emit(node.right);
                    write(")");
                    if (shouldEmitParentheses) {
                        write(")");
                    }
                }
                else {
                    write("Math.pow(");
                    emit(leftHandSideExpression);
                    write(", ");
                    emit(node.right);
                    write(")");
                }
            }

function
emitExponentiationOperator
(
node
)
{
var
leftHandSideExpression
=
node
.
left
;
if
(
node
.
operatorToken
.
kind
===
60
)
{
var
synthesizedLHS
;
var
shouldEmitParentheses
=
false
;
if
(
ts
.
isElementAccessExpression
(
leftHandSideExpression
)
)
{
shouldEmitParentheses
=
true
;
write
(
"("
)
;
synthesizedLHS
=
ts
.
createSynthesizedNode
(
167
,
false
)
;
var
identifier
=
emitTempVariableAssignment
(
leftHandSideExpression
.
expression
,
false
,
false
)
;
synthesizedLHS
.
expression
=
identifier
;
if
(
leftHandSideExpression
.
argumentExpression
.
kind
!==
8
&&
leftHandSideExpression
.
argumentExpression
.
kind
!==
9
)
{
var
tempArgumentExpression
=
createAndRecordTempVariable
(
268435456
)
;
synthesizedLHS
.
argumentExpression
=
tempArgumentExpression
;
emitAssignment
(
tempArgumentExpression
,
leftHandSideExpression
.
argumentExpression
,
true
)
;
}
else
{
synthesizedLHS
.
argumentExpression
=
leftHandSideExpression
.
argumentExpression
;
}
write
(
", "
)
;
}
else
if
(
ts
.
isPropertyAccessExpression
(
leftHandSideExpression
)
)
{
shouldEmitParentheses
=
true
;
write
(
"("
)
;
synthesizedLHS
=
ts
.
createSynthesizedNode
(
166
,
false
)
;
var
identifier
=
emitTempVariableAssignment
(
leftHandSideExpression
.
expression
,
false
,
false
)
;
synthesizedLHS
.
expression
=
identifier
;
synthesizedLHS
.
dotToken
=
leftHandSideExpression
.
dotToken
;
synthesizedLHS
.
name
=
leftHandSideExpression
.
name
;
write
(
", "
)
;
}
emit
(
synthesizedLHS
||
leftHandSideExpression
)
;
write
(
" = "
)
;
write
(
"Math.pow("
)
;
emit
(
synthesizedLHS
||
leftHandSideExpression
)
;
write
(
", "
)
;
emit
(
node
.
right
)
;
write
(
")"
)
;
if
(
shouldEmitParentheses
)
{
write
(
")"
)
;
}
}
else
{
write
(
"Math.pow("
)
;
emit
(
leftHandSideExpression
)
;
write
(
", "
)
;
emit
(
node
.
right
)
;
write
(
")"
)
;
}
}

Emit ES7 exponentiation operator downlevel using Math.pow
@param node a binary expression node containing exponentiationOperator (**, **=)

Emit ES7 exponentiation operator downlevel using Math . pow


function tryEmitStartOfVariableDeclarationList(decl, startPos) {
                if (shouldHoistVariable(decl, /*checkIfSourceFileLevelDecl*/ true)) {
                    // variables in variable declaration list were already hoisted
                    return false;
                }
                var tokenKind = 102 /* VarKeyword */;
                if (decl && languageVersion >= 2 /* ES6 */) {
                    if (ts.isLet(decl)) {
                        tokenKind = 108 /* LetKeyword */;
                    }
                    else if (ts.isConst(decl)) {
                        tokenKind = 74 /* ConstKeyword */;
                    }
                }
                if (startPos !== undefined) {
                    emitToken(tokenKind, startPos);
                    write(" ");
                }
                else {
                    switch (tokenKind) {
                        case 102 /* VarKeyword */:
                            write("var ");
                            break;
                        case 108 /* LetKeyword */:
                            write("let ");
                            break;
                        case 74 /* ConstKeyword */:
                            write("const ");
                            break;
                    }
                }
                return true;
            }

function
tryEmitStartOfVariableDeclarationList
(
decl
,
startPos
)
{
if
(
shouldHoistVariable
(
decl
,
true
)
)
{
return
false
;
}
var
tokenKind
=
102
;
if
(
decl
&&
languageVersion
>=
2
)
{
if
(
ts
.
isLet
(
decl
)
)
{
tokenKind
=
108
;
}
else
if
(
ts
.
isConst
(
decl
)
)
{
tokenKind
=
74
;
}
}
if
(
startPos
!==
undefined
)
{
emitToken
(
tokenKind
,
startPos
)
;
write
(
" "
)
;
}
else
{
switch
(
tokenKind
)
{
case
102
:
write
(
"var "
)
;
break
;
case
108
:
write
(
"let "
)
;
break
;
case
74
:
write
(
"const "
)
;
break
;
}
}
return
true
;
}

Returns true if start of variable declaration list was emitted.
Returns false if nothing was written - this can happen for source file level variable declarations
in system modules where such variable declarations are hoisted.

Returns true if start of variable declaration list was emitted . Returns false if nothing was written - this can happen for source file level variable declarations in system modules where such variable declarations are hoisted .


function emitAssignment(name, value, shouldEmitCommaBeforeAssignment) {
                if (shouldEmitCommaBeforeAssignment) {
                    write(", ");
                }
                var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(name);
                if (exportChanged) {
                    write(exportFunctionForFile + "(\"");
                    emitNodeWithCommentsAndWithoutSourcemap(name);
                    write("\", ");
                }
                var isVariableDeclarationOrBindingElement = name.parent && (name.parent.kind === 211 /* VariableDeclaration */ || name.parent.kind === 163 /* BindingElement */);
                if (isVariableDeclarationOrBindingElement) {
                    emitModuleMemberName(name.parent);
                }
                else {
                    emit(name);
                }
                write(" = ");
                emit(value);
                if (exportChanged) {
                    write(")");
                }
            }

Emit an assignment to a given identifier, 'name', with a given expression, 'value'.
@param name an identifier as a left-hand-side operand of the assignment
@param value an expression as a right-hand-side operand of the assignment
@param shouldEmitCommaBeforeAssignment a boolean indicating whether to prefix an assignment with comma

Emit an assignment to a given identifier name with a given expression value .


function emitTempVariableAssignment(expression, canDefineTempVariablesInPlace, shouldEmitCommaBeforeAssignment) {
                var identifier = createTempVariable(0 /* Auto */);
                if (!canDefineTempVariablesInPlace) {
                    recordTempDeclaration(identifier);
                }
                emitAssignment(identifier, expression, shouldEmitCommaBeforeAssignment);
                return identifier;
            }

function emitTempVariableAssignment ( expression , canDefineTempVariablesInPlace , shouldEmitCommaBeforeAssignment ) { var identifier = createTempVariable ( 0 ) ; if ( ! canDefineTempVariablesInPlace ) { recordTempDeclaration ( identifier ) ; } emitAssignment ( identifier , expression , shouldEmitCommaBeforeAssignment ) ; return identifier ; }

Create temporary variable, emit an assignment of the variable the given expression
@param expression an expression to assign to the newly created temporary variable
@param canDefineTempVariablesInPlace a boolean indicating whether you can define the temporary variable at an assignment location
@param shouldEmitCommaBeforeAssignment a boolean indicating whether an assignment should prefix with comma

Create temporary variable emit an assignment of the variable the given expression


function ensureIdentifier(expr, reuseIdentifierExpressions) {
                    if (expr.kind === 69 /* Identifier */ && reuseIdentifierExpressions) {
                        return expr;
                    }
                    var identifier = emitTempVariableAssignment(expr, canDefineTempVariablesInPlace, emitCount > 0);
                    emitCount++;
                    return identifier;
                }

function ensureIdentifier ( expr , reuseIdentifierExpressions ) { if ( expr . kind === 69 && reuseIdentifierExpressions ) { return expr ; } var identifier = emitTempVariableAssignment ( expr , canDefineTempVariablesInPlace , emitCount > 0 ) ; emitCount ++ ; return identifier ; }

Ensures that there exists a declared identifier whose value holds the given expression.
This function is useful to ensure that the expression's value can be read from in subsequent expressions.
Unless 'reuseIdentifierExpressions' is false, 'expr' will be returned if it is just an identifier.

@param expr the expression whose value needs to be bound.
@param reuseIdentifierExpressions true if identifier expressions can simply be returned;
false if it is necessary to always emit an identifier.

Ensures that there exists a declared identifier whose value holds the given expression . This function is useful to ensure that the expression s value can be read from in subsequent expressions . Unless reuseIdentifierExpressions is false expr will be returned if it is just an identifier .


function findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd) {
            if (filesByName.contains(fileName)) {
                // We've already looked for this file, use cached result
                return getSourceFileFromCache(fileName, /*useAbsolutePath*/ false);
            }
            var normalizedAbsolutePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
            if (filesByName.contains(normalizedAbsolutePath)) {
                var file_1 = getSourceFileFromCache(normalizedAbsolutePath, /*useAbsolutePath*/ true);
                // we don't have resolution for this relative file name but the match was found by absolute file name
                // store resolution for relative name as well
                filesByName.set(fileName, file_1);
                return file_1;
            }
            // We haven't looked for this file, do so now and cache result
            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) {
                if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
                else {
                    fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
                }
            });
            filesByName.set(fileName, file);
            if (file) {
                skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
                // Set the source file for normalized absolute path
                filesByName.set(normalizedAbsolutePath, file);
                var basePath = ts.getDirectoryPath(fileName);
                if (!options.noResolve) {
                    processReferencedFiles(file, basePath);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file, basePath);
                if (isDefaultLib) {
                    file.isDefaultLib = true;
                    files.unshift(file);
                }
                else {
                    files.push(file);
                }
            }
            return file;
            function getSourceFileFromCache(fileName, useAbsolutePath) {
                var file = filesByName.get(fileName);
                if (file && host.useCaseSensitiveFileNames()) {
                    var sourceFileName = useAbsolutePath ? ts.getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
                    if (ts.normalizeSlashes(fileName) !== ts.normalizeSlashes(sourceFileName)) {
                        if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
                            fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
                        }
                        else {
                            fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
                        }
                    }
                }
                return file;
            }
        }

Get source file from normalized fileName


function readConfigFile(fileName, readFile) {
        var text = "";
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return { error: ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message) };
        }
        return parseConfigFileTextToJson(fileName, text);
    }

function readConfigFile ( fileName , readFile ) { var text = "" ; try { text = readFile ( fileName ) ; } catch ( e ) { return { error : ts . createCompilerDiagnostic ( ts . Diagnostics . Cannot_read_file_0_Colon_1 , fileName , e . message ) } ; } return parseConfigFileTextToJson ( fileName , text ) ; }

Read tsconfig.json file
@param fileName The path to the config file


function parseConfigFileTextToJson(fileName, jsonText) {
        try {
            return { config: /\S/.test(jsonText) ? JSON.parse(jsonText) : {} };
        }
        catch (e) {
            return { error: ts.createCompilerDiagnostic(ts.Diagnostics.Failed_to_parse_file_0_Colon_1, fileName, e.message) };
        }
    }

function parseConfigFileTextToJson ( fileName , jsonText ) { try { return { config : / \S / . test ( jsonText ) ? JSON . parse ( jsonText ) : { } } ; } catch ( e ) { return { error : ts . createCompilerDiagnostic ( ts . Diagnostics . Failed_to_parse_file_0_Colon_1 , fileName , e . message ) } ; } }

Parse the text of the tsconfig.json file
@param fileName The path to the config file
@param jsonText The text of the config file

Parse the text of the tsconfig . json file


function removeDynamicallyNamedProperties(node) {
                return ts.filter(node.members, function (member) { return !ts.hasDynamicName(member); });
            }

function removeDynamicallyNamedProperties ( node ) { return ts . filter ( node . members , function ( member ) { return ! ts . hasDynamicName ( member ) ; } ) ; }

Like removeComputedProperties, but retains the properties with well known symbol names

Like removeComputedProperties but retains the properties with well known symbol names


function getImmediatelyContainingArgumentInfo(node) {
                if (node.parent.kind === 168 /* CallExpression */ || node.parent.kind === 169 /* NewExpression */) {
                    var callExpression = node.parent;
                    // There are 3 cases to handle:
                    //   1. The token introduces a list, and should begin a sig help session
                    //   2. The token is either not associated with a list, or ends a list, so the session should end
                    //   3. The token is buried inside a list, and should give sig help
                    //
                    // The following are examples of each:
                    //
                    //    Case 1:
                    //          foo<#T, U>(#a, b)    -> The token introduces a list, and should begin a sig help session
                    //    Case 2:
                    //          fo#o<T, U>#(a, b)#   -> The token is either not associated with a list, or ends a list, so the session should end
                    //    Case 3:
                    //          foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give sig help
                    // Find out if 'node' is an argument, a type argument, or neither
                    if (node.kind === 25 /* LessThanToken */ ||
                        node.kind === 17 /* OpenParenToken */) {
                        // Find the list that starts right *after* the < or ( token.
                        // If the user has just opened a list, consider this item 0.
                        var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile);
                        var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                        ts.Debug.assert(list !== undefined);
                        return {
                            kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                            invocation: callExpression,
                            argumentsSpan: getApplicableSpanForArguments(list),
                            argumentIndex: 0,
                            argumentCount: getArgumentCount(list)
                        };
                    }
                    // findListItemInfo can return undefined if we are not in parent's argument list
                    // or type argument list. This includes cases where the cursor is:
                    //   - To the right of the closing paren, non-substitution template, or template tail.
                    //   - Between the type arguments and the arguments (greater than token)
                    //   - On the target of the call (parent.func)
                    //   - On the 'new' keyword in a 'new' expression
                    var listItemInfo = ts.findListItemInfo(node);
                    if (listItemInfo) {
                        var list = listItemInfo.list;
                        var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                        var argumentIndex = getArgumentIndex(list, node);
                        var argumentCount = getArgumentCount(list);
                        ts.Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, "argumentCount < argumentIndex, " + argumentCount + " < " + argumentIndex);
                        return {
                            kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                            invocation: callExpression,
                            argumentsSpan: getApplicableSpanForArguments(list),
                            argumentIndex: argumentIndex,
                            argumentCount: argumentCount
                        };
                    }
                }
                else if (node.kind === 11 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 170 /* TaggedTemplateExpression */) {
                    // Check if we're actually inside the template;
                    // otherwise we'll fall out and return undefined.
                    if (ts.isInsideTemplateLiteral(node, position)) {
                        return getArgumentListInfoForTemplate(node.parent, /*argumentIndex*/ 0);
                    }
                }
                else if (node.kind === 12 /* TemplateHead */ && node.parent.parent.kind === 170 /* TaggedTemplateExpression */) {
                    var templateExpression = node.parent;
                    var tagExpression = templateExpression.parent;
                    ts.Debug.assert(templateExpression.kind === 183 /* TemplateExpression */);
                    var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1;
                    return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
                }
                else if (node.parent.kind === 190 /* TemplateSpan */ && node.parent.parent.parent.kind === 170 /* TaggedTemplateExpression */) {
                    var templateSpan = node.parent;
                    var templateExpression = templateSpan.parent;
                    var tagExpression = templateExpression.parent;
                    ts.Debug.assert(templateExpression.kind === 183 /* TemplateExpression */);
                    // If we're just after a template tail, don't show signature help.
                    if (node.kind === 14 /* TemplateTail */ && !ts.isInsideTemplateLiteral(node, position)) {
                        return undefined;
                    }
                    var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
                    var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node);
                    return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
                }
                return undefined;
            }

function
getImmediatelyContainingArgumentInfo
(
node
)
{
if
(
node
.
parent
.
kind
===
168
||
node
.
parent
.
kind
===
169
)
{
var
callExpression
=
node
.
parent
;
if
(
node
.
kind
===
25
||
node
.
kind
===
17
)
{
var
list
=
getChildListThatStartsWithOpenerToken
(
callExpression
,
node
,
sourceFile
)
;
var
isTypeArgList
=
callExpression
.
typeArguments
&&
callExpression
.
typeArguments
.
pos
===
list
.
pos
;
ts
.
Debug
.
assert
(
list
!==
undefined
)
;
return
{
kind
:
isTypeArgList
0
:
1
,
invocation
:
callExpression
,
argumentsSpan
:
getApplicableSpanForArguments
(
list
)
,
argumentIndex
:
0
,
argumentCount
:
getArgumentCount
(
list
)
}
;
}
var
listItemInfo
=
ts
.
findListItemInfo
(
node
)
;
if
(
listItemInfo
)
{
var
list
=
listItemInfo
.
list
;
var
isTypeArgList
=
callExpression
.
typeArguments
&&
callExpression
.
typeArguments
.
pos
===
list
.
pos
;
var
argumentIndex
=
getArgumentIndex
(
list
,
node
)
;
var
argumentCount
=
getArgumentCount
(
list
)
;
ts
.
Debug
.
assert
(
argumentIndex
===
0
||
argumentIndex
<
argumentCount
,
"argumentCount < argumentIndex, "
+
argumentCount
+
" < "
+
argumentIndex
)
;
return
{
kind
:
isTypeArgList
0
:
1
,
invocation
:
callExpression
,
argumentsSpan
:
getApplicableSpanForArguments
(
list
)
,
argumentIndex
:
argumentIndex
,
argumentCount
:
argumentCount
}
;
}
}
else
if
(
node
.
kind
===
11
&&
node
.
parent
.
kind
===
170
)
{
if
(
ts
.
isInsideTemplateLiteral
(
node
,
position
)
)
{
return
getArgumentListInfoForTemplate
(
node
.
parent
,
0
)
;
}
}
else
if
(
node
.
kind
===
12
&&
node
.
parent
.
parent
.
kind
===
170
)
{
var
templateExpression
=
node
.
parent
;
var
tagExpression
=
templateExpression
.
parent
;
ts
.
Debug
.
assert
(
templateExpression
.
kind
===
183
)
;
var
argumentIndex
=
ts
.
isInsideTemplateLiteral
(
node
,
position
)
0
:
1
;
return
getArgumentListInfoForTemplate
(
tagExpression
,
argumentIndex
)
;
}
else
if
(
node
.
parent
.
kind
===
190
&&
node
.
parent
.
parent
.
parent
.
kind
===
170
)
{
var
templateSpan
=
node
.
parent
;
var
templateExpression
=
templateSpan
.
parent
;
var
tagExpression
=
templateExpression
.
parent
;
ts
.
Debug
.
assert
(
templateExpression
.
kind
===
183
)
;
if
(
node
.
kind
===
14
&&
!
ts
.
isInsideTemplateLiteral
(
node
,
position
)
)
{
return
undefined
;
}
var
spanIndex
=
templateExpression
.
templateSpans
.
indexOf
(
templateSpan
)
;
var
argumentIndex
=
getArgumentIndexForTemplatePiece
(
spanIndex
,
node
)
;
return
getArgumentListInfoForTemplate
(
tagExpression
,
argumentIndex
)
;
}
return
undefined
;
}

Returns relevant information for the argument list and the current argument if we are
in the argument of an invocation; returns undefined otherwise.

Returns relevant information for the argument list and the current argument if we are in the argument of an invocation ; returns undefined otherwise .


function selectBestInvalidOverloadIndex(candidates, argumentCount) {
                var maxParamsSignatureIndex = -1;
                var maxParams = -1;
                for (var i = 0; i < candidates.length; i++) {
                    var candidate = candidates[i];
                    if (candidate.hasRestParameter || candidate.parameters.length >= argumentCount) {
                        return i;
                    }
                    if (candidate.parameters.length > maxParams) {
                        maxParams = candidate.parameters.length;
                        maxParamsSignatureIndex = i;
                    }
                }
                return maxParamsSignatureIndex;
            }

function selectBestInvalidOverloadIndex ( candidates , argumentCount ) { var maxParamsSignatureIndex = - 1 ; var maxParams = - 1 ; for ( var i = 0 ; i < candidates . length ; i ++ ) { var candidate = candidates [ i ] ; if ( candidate . hasRestParameter || candidate . parameters . length >= argumentCount ) { return i ; } if ( candidate . parameters . length > maxParams ) { maxParams = candidate . parameters . length ; maxParamsSignatureIndex = i ; } } return maxParamsSignatureIndex ; }

The selectedItemIndex could be negative for several reasons.
1. There are too many arguments for all of the overloads
2. None of the overloads were type compatible
The solution here is to try to pick the best overload by picking
either the first one that has an appropriate number of parameters,
or the one with the most parameters.

The selectedItemIndex could be negative for several reasons . 1 . There are too many arguments for all of the overloads 2 . None of the overloads were type compatible The solution here is to try to pick the best overload by picking either the first one that has an appropriate number of parameters or the one with the most parameters .


function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includeItemAtEndPosition) {
        var current = sourceFile;
        outer: while (true) {
            if (isToken(current)) {
                // exit early
                return current;
            }
            // find the child that contains 'position'
            for (var i = 0, n = current.getChildCount(sourceFile); i < n; i++) {
                var child = current.getChildAt(i);
                var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile);
                if (start <= position) {
                    var end = child.getEnd();
                    if (position < end || (position === end && child.kind === 1 /* EndOfFileToken */)) {
                        current = child;
                        continue outer;
                    }
                    else if (includeItemAtEndPosition && end === position) {
                        var previousToken = findPrecedingToken(position, sourceFile, child);
                        if (previousToken && includeItemAtEndPosition(previousToken)) {
                            return previousToken;
                        }
                    }
                }
            }
            return current;
        }
    }

function getTokenAtPositionWorker ( sourceFile , position , allowPositionInLeadingTrivia , includeItemAtEndPosition ) { var current = sourceFile ; outer : while ( true ) { if ( isToken ( current ) ) { return current ; } for ( var i = 0 , n = current . getChildCount ( sourceFile ) ; i < n ; i ++ ) { var child = current . getChildAt ( i ) ; var start = allowPositionInLeadingTrivia ? child . getFullStart ( ) : child . getStart ( sourceFile ) ; if ( start <= position ) { var end = child . getEnd ( ) ; if ( position < end || ( position === end && child . kind === 1 ) ) { current = child ; continue outer ; } else if ( includeItemAtEndPosition && end === position ) { var previousToken = findPrecedingToken ( position , sourceFile , child ) ; if ( previousToken && includeItemAtEndPosition ( previousToken ) ) { return previousToken ; } } } } return current ; } }

Get the token whose text contains the position


function findTokenOnLeftOfPosition(file, position) {
        // Ideally, getTokenAtPosition should return a token. However, it is currently
        // broken, so we do a check to make sure the result was indeed a token.
        var tokenAtPosition = getTokenAtPosition(file, position);
        if (isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
            return tokenAtPosition;
        }
        return findPrecedingToken(position, file);
    }

function findTokenOnLeftOfPosition ( file , position ) { var tokenAtPosition = getTokenAtPosition ( file , position ) ; if ( isToken ( tokenAtPosition ) && position > tokenAtPosition . getStart ( file ) && position < tokenAtPosition . getEnd ( ) ) { return tokenAtPosition ; } return findPrecedingToken ( position , file ) ; }

The token on the left of the position is the token that strictly includes the position
or sits to the left of the cursor if it is on a boundary. For example

fo|o               -> will return foo
foo <comment> |bar -> will return foo

The token on the left of the position is the token that strictly includes the position or sits to the left of the cursor if it is on a boundary . For example


function getJsDocTagAtPosition(sourceFile, position) {
        var node = ts.getTokenAtPosition(sourceFile, position);
        if (isToken(node)) {
            switch (node.kind) {
                case 102 /* VarKeyword */:
                case 108 /* LetKeyword */:
                case 74 /* ConstKeyword */:
                    // if the current token is var, let or const, skip the VariableDeclarationList
                    node = node.parent === undefined ? undefined : node.parent.parent;
                    break;
                default:
                    node = node.parent;
                    break;
            }
        }
        if (node) {
            var jsDocComment = node.jsDocComment;
            if (jsDocComment) {
                for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) {
                    var tag = _a[_i];
                    if (tag.pos <= position && position <= tag.end) {
                        return tag;
                    }
                }
            }
        }
        return undefined;
    }

function getJsDocTagAtPosition ( sourceFile , position ) { var node = ts . getTokenAtPosition ( sourceFile , position ) ; if ( isToken ( node ) ) { switch ( node . kind ) { case 102 : case 108 : case 74 : node = node . parent === undefined ? undefined : node . parent . parent ; break ; default : node = node . parent ; break ; } } if ( node ) { var jsDocComment = node . jsDocComment ; if ( jsDocComment ) { for ( var _i = 0 , _a = jsDocComment . tags ; _i < _a . length ; _i ++ ) { var tag = _a [ _i ] ; if ( tag . pos <= position && position <= tag . end ) { return tag ; } } } } return undefined ; }

Get the corresponding JSDocTag node if the position is in a jsDoc comment


function stripQuotes(name) {
        var length = name.length;
        if (length >= 2 &&
            name.charCodeAt(0) === name.charCodeAt(length - 1) &&
            (name.charCodeAt(0) === 34 /* doubleQuote */ || name.charCodeAt(0) === 39 /* singleQuote */)) {
            return name.substring(1, length - 1);
        }
        ;
        return name;
    }

function stripQuotes ( name ) { var length = name . length ; if ( length >= 2 && name . charCodeAt ( 0 ) === name . charCodeAt ( length - 1 ) && ( name . charCodeAt ( 0 ) === 34 || name . charCodeAt ( 0 ) === 39 ) ) { return name . substring ( 1 , length - 1 ) ; } ; return name ; }

Strip off existed single quotes or double quotes from a given string

@return non-quoted string


function fixTokenKind(tokenInfo, container) {
                if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) {
                    tokenInfo.token.kind = container.kind;
                }
                return tokenInfo;
            }

function fixTokenKind ( tokenInfo , container ) { if ( ts . isToken ( container ) && tokenInfo . token . kind !== container . kind ) { tokenInfo . token . kind = container . kind ; } return tokenInfo ; }

when containing node in the tree is token but its kind differs from the kind that was returned by the scanner, then kind needs to be fixed. This might happen in cases when parser interprets token differently, i.e keyword treated as identifier

when containing node in the tree is token but its kind differs from the kind that was returned by the scanner then kind needs to be fixed . This might happen in cases when parser interprets token differently i . e keyword treated as identifier


function isListElement(parent, node) {
            switch (parent.kind) {
                case 214 /* ClassDeclaration */:
                case 215 /* InterfaceDeclaration */:
                    return ts.rangeContainsRange(parent.members, node);
                case 218 /* ModuleDeclaration */:
                    var body = parent.body;
                    return body && body.kind === 192 /* Block */ && ts.rangeContainsRange(body.statements, node);
                case 248 /* SourceFile */:
                case 192 /* Block */:
                case 219 /* ModuleBlock */:
                    return ts.rangeContainsRange(parent.statements, node);
                case 244 /* CatchClause */:
                    return ts.rangeContainsRange(parent.block.statements, node);
            }
            return false;
        }

function isListElement ( parent , node ) { switch ( parent . kind ) { case 214 : case 215 : return ts . rangeContainsRange ( parent . members , node ) ; case 218 : var body = parent . body ; return body && body . kind === 192 && ts . rangeContainsRange ( body . statements , node ) ; case 248 : case 192 : case 219 : return ts . rangeContainsRange ( parent . statements , node ) ; case 244 : return ts . rangeContainsRange ( parent . block . statements , node ) ; } return false ; }

Returns true if node is a element in some list in parent i.e. parent is class declaration with the list of members and node is one of members.

Returns true if node is a element in some list in parent i . e . parent is class declaration with the list of members and node is one of members .


function findEnclosingNode(range, sourceFile) {
            return find(sourceFile);
            function find(n) {
                var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
                if (candidate) {
                    var result = find(candidate);
                    if (result) {
                        return result;
                    }
                }
                return n;
            }
        }

function findEnclosingNode ( range , sourceFile ) { return find ( sourceFile ) ; function find ( n ) { var candidate = ts . forEachChild ( n , function ( c ) { return ts . startEndContainsRange ( c . getStart ( sourceFile ) , c . end , range ) && c ; } ) ; if ( candidate ) { var result = find ( candidate ) ; if ( result ) { return result ; } } return n ; } }

find node that fully contains given text range


function prepareRangeContainsErrorFunction(errors, originalRange) {
            if (!errors.length) {
                return rangeHasNoErrors;
            }
            // pick only errors that fall in range
            var sorted = errors
                .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); })
                .sort(function (e1, e2) { return e1.start - e2.start; });
            if (!sorted.length) {
                return rangeHasNoErrors;
            }
            var index = 0;
            return function (r) {
                // in current implementation sequence of arguments [r1, r2...] is monotonically increasing.
                // 'index' tracks the index of the most recent error that was checked.
                while (true) {
                    if (index >= sorted.length) {
                        // all errors in the range were already checked -> no error in specified range
                        return false;
                    }
                    var error = sorted[index];
                    if (r.end <= error.start) {
                        // specified range ends before the error refered by 'index' - no error in range
                        return false;
                    }
                    if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
                        // specified range overlaps with error range
                        return true;
                    }
                    index++;
                }
            };
            function rangeHasNoErrors(r) {
                return false;
            }
        }

function prepareRangeContainsErrorFunction ( errors , originalRange ) { if ( ! errors . length ) { return rangeHasNoErrors ; } var sorted = errors . filter ( function ( d ) { return ts . rangeOverlapsWithStartEnd ( originalRange , d . start , d . start + d . length ) ; } ) . sort ( function ( e1 , e2 ) { return e1 . start - e2 . start ; } ) ; if ( ! sorted . length ) { return rangeHasNoErrors ; } var index = 0 ; return function ( r ) { while ( true ) { if ( index >= sorted . length ) { return false ; } var error = sorted [ index ] ; if ( r . end <= error . start ) { return false ; } if ( ts . startEndOverlapsWithStartEnd ( r . pos , r . end , error . start , error . start + error . length ) ) { return true ; } index ++ ; } } ; function rangeHasNoErrors ( r ) { return false ; } }

formatting is not applied to ranges that contain parse errors.
This function will return a predicate that for a given text range will tell
if there are any parse errors that overlap with the range.

formatting is not applied to ranges that contain parse errors . This function will return a predicate that for a given text range will tell if there are any parse errors that overlap with the range .


function isInsideComment(sourceFile, token, position) {
        // The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment
        return position <= token.getStart(sourceFile) &&
            (isInsideCommentRange(ts.getTrailingCommentRanges(sourceFile.text, token.getFullStart())) ||
            isInsideCommentRange(ts.getLeadingCommentRanges(sourceFile.text, token.getFullStart())));
        function isInsideCommentRange(comments) {
            return ts.forEach(comments, function (comment) {
                // either we are 1. completely inside the comment, or 2. at the end of the comment
                if (comment.pos < position && position < comment.end) {
                    return true;
                }
                else if (position === comment.end) {
                    var text = sourceFile.text;
                    var width = comment.end - comment.pos;
                    // is single line comment or just /*
                    if (width <= 2 || text.charCodeAt(comment.pos + 1) === 47 /* slash */) {
                        return true;
                    }
                    else {
                        // is unterminated multi-line comment
                        return !(text.charCodeAt(comment.end - 1) === 47 /* slash */ &&
                        text.charCodeAt(comment.end - 2) === 42 /* asterisk */);
                    }
                }
                return false;
            });
        }
    }

function isInsideComment ( sourceFile , token , position ) { return position <= token . getStart ( sourceFile ) && ( isInsideCommentRange ( ts . getTrailingCommentRanges ( sourceFile . text , token . getFullStart ( ) ) ) || isInsideCommentRange ( ts . getLeadingCommentRanges ( sourceFile . text , token . getFullStart ( ) ) ) ) ; function isInsideCommentRange ( comments ) { return ts . forEach ( comments , function ( comment ) { if ( comment . pos < position && position < comment . end ) { return true ; } else if ( position === comment . end ) { var text = sourceFile . text ; var width = comment . end - comment . pos ; if ( width <= 2 || text . charCodeAt ( comment . pos + 1 ) === 47 ) { return true ; } else { return ! ( text . charCodeAt ( comment . end - 1 ) === 47 && text . charCodeAt ( comment . end - 2 ) === 42 ) ; } } return false ; } ) ; } }

Returns true if the position is within a comment


function getSemanticDiagnostics(fileName) {
            synchronizeHostData();
            var targetSourceFile = getValidSourceFile(fileName);
            // For JavaScript files, we don't want to report the normal typescript semantic errors.
            // Instead, we just report errors for using TypeScript-only constructs from within a
            // JavaScript file.
            if (ts.isJavaScript(fileName)) {
                return getJavaScriptSemanticDiagnostics(targetSourceFile);
            }
            // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
            // Therefore only get diagnostics for given file.
            var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
            if (!program.getCompilerOptions().declaration) {
                return semanticDiagnostics;
            }
            // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
            var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
            return ts.concatenate(semanticDiagnostics, declarationDiagnostics);
        }

function getSemanticDiagnostics ( fileName ) { synchronizeHostData ( ) ; var targetSourceFile = getValidSourceFile ( fileName ) ; if ( ts . isJavaScript ( fileName ) ) { return getJavaScriptSemanticDiagnostics ( targetSourceFile ) ; } var semanticDiagnostics = program . getSemanticDiagnostics ( targetSourceFile , cancellationToken ) ; if ( ! program . getCompilerOptions ( ) . declaration ) { return semanticDiagnostics ; } var declarationDiagnostics = program . getDeclarationDiagnostics ( targetSourceFile , cancellationToken ) ; return ts . concatenate ( semanticDiagnostics , declarationDiagnostics ) ; }

getSemanticDiagnostiscs return array of Diagnostics. If '-d' is not enabled, only report semantic errors
If '-d' enabled, report both semantic and emitter errors

getSemanticDiagnostiscs return array of Diagnostics . If - d is not enabled only report semantic errors If - d enabled report both semantic and emitter errors


function getCompletionEntryDisplayName(name, target, performCharacterChecks) {
            if (!name) {
                return undefined;
            }
            name = ts.stripQuotes(name);
            if (!name) {
                return undefined;
            }
            // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
            // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
            // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid.
            // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name.
            if (performCharacterChecks) {
                if (!ts.isIdentifierStart(name.charCodeAt(0), target)) {
                    return undefined;
                }
                for (var i = 1, n = name.length; i < n; i++) {
                    if (!ts.isIdentifierPart(name.charCodeAt(i), target)) {
                        return undefined;
                    }
                }
            }
            return name;
        }

function getCompletionEntryDisplayName ( name , target , performCharacterChecks ) { if ( ! name ) { return undefined ; } name = ts . stripQuotes ( name ) ; if ( ! name ) { return undefined ; } if ( performCharacterChecks ) { if ( ! ts . isIdentifierStart ( name . charCodeAt ( 0 ) , target ) ) { return undefined ; } for ( var i = 1 , n = name . length ; i < n ; i ++ ) { if ( ! ts . isIdentifierPart ( name . charCodeAt ( i ) , target ) ) { return undefined ; } } } return name ; }

Get a displayName from a given for completion list, performing any necessary quotes stripping
and checking whether the name is valid identifier name.

Get a displayName from a given for completion list performing any necessary quotes stripping and checking whether the name is valid identifier name .


function getScopeNode(initialToken, position, sourceFile) {
                var scope = initialToken;
                while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) {
                    scope = scope.parent;
                }
                return scope;
            }

function getScopeNode ( initialToken , position , sourceFile ) { var scope = initialToken ; while ( scope && ! ts . positionBelongsToNode ( scope , position , sourceFile ) ) { scope = scope . parent ; } return scope ; }

Finds the first node that "embraces" the position, so that one may
accurately aggregate locals from the closest containing scope.

Finds the first node that embraces the position so that one may accurately aggregate locals from the closest containing scope .


function tryGetObjectLikeCompletionSymbols(objectLikeContainer) {
                // We're looking up possible property names from contextual/inferred/declared type.
                isMemberCompletion = true;
                var typeForObject;
                var existingMembers;
                if (objectLikeContainer.kind === 165 /* ObjectLiteralExpression */) {
                    // We are completing on contextual types, but may also include properties
                    // other than those within the declared type.
                    isNewIdentifierLocation = true;
                    typeForObject = typeChecker.getContextualType(objectLikeContainer);
                    existingMembers = objectLikeContainer.properties;
                }
                else if (objectLikeContainer.kind === 161 /* ObjectBindingPattern */) {
                    // We are *only* completing on properties from the type being destructured.
                    isNewIdentifierLocation = false;
                    var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent);
                    if (ts.isVariableLike(rootDeclaration)) {
                        // We don't want to complete using the type acquired by the shape
                        // of the binding pattern; we are only interested in types acquired
                        // through type declaration or inference.
                        if (rootDeclaration.initializer || rootDeclaration.type) {
                            typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
                            existingMembers = objectLikeContainer.elements;
                        }
                    }
                    else {
                        ts.Debug.fail("Root declaration is not variable-like.");
                    }
                }
                else {
                    ts.Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);
                }
                if (!typeForObject) {
                    return false;
                }
                var typeMembers = typeChecker.getPropertiesOfType(typeForObject);
                if (typeMembers && typeMembers.length > 0) {
                    // Add filtered items to the completion list
                    symbols = filterObjectMembersList(typeMembers, existingMembers);
                }
                return true;
            }

Aggregates relevant symbols for completion in object literals and object binding patterns.
Relevant symbols are stored in the captured 'symbols' variable.

@returns true if 'symbols' was successfully populated; false otherwise.

Aggregates relevant symbols for completion in object literals and object binding patterns . Relevant symbols are stored in the captured symbols variable .


function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) {
                var declarationKind = namedImportsOrExports.kind === 225 /* NamedImports */ ?
                    222 /* ImportDeclaration */ :
                    228 /* ExportDeclaration */;
                var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind);
                var moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
                if (!moduleSpecifier) {
                    return false;
                }
                isMemberCompletion = true;
                isNewIdentifierLocation = false;
                var exports;
                var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier);
                if (moduleSpecifierSymbol) {
                    exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol);
                }
                symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray;
                return true;
            }

Aggregates relevant symbols for completion in import clauses and export clauses
whose declarations have a module specifier; for instance, symbols will be aggregated for

import { | } from "moduleName";
export { a as foo, | } from "moduleName";

but not for

export { | };

Relevant symbols are stored in the captured 'symbols' variable.

@returns true if 'symbols' was successfully populated; false otherwise.

Aggregates relevant symbols for completion in import clauses and export clauses whose declarations have a module specifier ; for instance symbols will be aggregated for


function tryGetObjectLikeCompletionContainer(contextToken) {
                if (contextToken) {
                    switch (contextToken.kind) {
                        case 15 /* OpenBraceToken */: // let x = { |
                        case 24 /* CommaToken */:
                            var parent_10 = contextToken.parent;
                            if (parent_10 && (parent_10.kind === 165 /* ObjectLiteralExpression */ || parent_10.kind === 161 /* ObjectBindingPattern */)) {
                                return parent_10;
                            }
                            break;
                    }
                }
                return undefined;
            }

function tryGetObjectLikeCompletionContainer ( contextToken ) { if ( contextToken ) { switch ( contextToken . kind ) { case 15 : case 24 : var parent_10 = contextToken . parent ; if ( parent_10 && ( parent_10 . kind === 165 || parent_10 . kind === 161 ) ) { return parent_10 ; } break ; } } return undefined ; }

Returns the immediate owning object literal or binding pattern of a context token,
on the condition that one exists and that the context implies completion should be given.

Returns the immediate owning object literal or binding pattern of a context token on the condition that one exists and that the context implies completion should be given .


function filterJsxAttributes(symbols, attributes) {
                var seenNames = {};
                for (var _i = 0; _i < attributes.length; _i++) {
                    var attr = attributes[_i];
                    // If this is the current item we are editing right now, do not filter it out
                    if (attr.getStart() <= position && position <= attr.getEnd()) {
                        continue;
                    }
                    if (attr.kind === 238 /* JsxAttribute */) {
                        seenNames[attr.name.text] = true;
                    }
                }
                return ts.filter(symbols, function (a) { return !ts.lookUp(seenNames, a.name); });
            }

function filterJsxAttributes ( symbols , attributes ) { var seenNames = { } ; for ( var _i = 0 ; _i < attributes . length ; _i ++ ) { var attr = attributes [ _i ] ; if ( attr . getStart ( ) <= position && position <= attr . getEnd ( ) ) { continue ; } if ( attr . kind === 238 ) { seenNames [ attr . name . text ] = true ; } } return ts . filter ( symbols , function ( a ) { return ! ts . lookUp ( seenNames , a . name ) ; } ) ; }

Filters out completion suggestions from 'symbols' according to existing JSX attributes.

@returns Symbols to be suggested in a JSX element, barring those whose attributes
do not occur at the current position and have not otherwise been typed.

Filters out completion suggestions from symbols according to existing JSX attributes .


function isWriteAccess(node) {
            if (node.kind === 69 /* Identifier */ && ts.isDeclarationName(node)) {
                return true;
            }
            var parent = node.parent;
            if (parent) {
                if (parent.kind === 180 /* PostfixUnaryExpression */ || parent.kind === 179 /* PrefixUnaryExpression */) {
                    return true;
                }
                else if (parent.kind === 181 /* BinaryExpression */ && parent.left === node) {
                    var operator = parent.operatorToken.kind;
                    return 56 /* FirstAssignment */ <= operator && operator <= 68 /* LastAssignment */;
                }
            }
            return false;
        }

function isWriteAccess ( node ) { if ( node . kind === 69 && ts . isDeclarationName ( node ) ) { return true ; } var parent = node . parent ; if ( parent ) { if ( parent . kind === 180 || parent . kind === 179 ) { return true ; } else if ( parent . kind === 181 && parent . left === node ) { var operator = parent . operatorToken . kind ; return 56 <= operator && operator <= 68 ; } } return false ; }

A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment


function getSignatureHelpItems(fileName, position) {
            synchronizeHostData();
            var sourceFile = getValidSourceFile(fileName);
            return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken);
        }

function getSignatureHelpItems ( fileName , position ) { synchronizeHostData ( ) ; var sourceFile = getValidSourceFile ( fileName ) ; return ts . SignatureHelp . getSignatureHelpItems ( program , sourceFile , position , cancellationToken ) ; }

Signature help
This is a semantic operation.

Signature help This is a semantic operation .


function hasValueSideModule(symbol) {
                    return ts.forEach(symbol.declarations, function (declaration) {
                        return declaration.kind === 218 /* ModuleDeclaration */ &&
                            ts.getModuleInstanceState(declaration) === 1 /* Instantiated */;
                    });
                }

function hasValueSideModule ( symbol ) { return ts . forEach ( symbol . declarations , function ( declaration ) { return declaration . kind === 218 && ts . getModuleInstanceState ( declaration ) === 1 ; } ) ; }

Returns true if there exists a module that introduces entities on the value side.

Returns true if there exists a module that introduces entities on the value side .


function classifyTokenType(tokenKind, token) {
                if (ts.isKeyword(tokenKind)) {
                    return 3 /* keyword */;
                }
                // Special case < and >  If they appear in a generic context they are punctuation,
                // not operators.
                if (tokenKind === 25 /* LessThanToken */ || tokenKind === 27 /* GreaterThanToken */) {
                    // If the node owning the token has a type argument list or type parameter list, then
                    // we can effectively assume that a '<' and '>' belong to those lists.
                    if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) {
                        return 10 /* punctuation */;
                    }
                }
                if (ts.isPunctuation(tokenKind)) {
                    if (token) {
                        if (tokenKind === 56 /* EqualsToken */) {
                            // the '=' in a variable declaration is special cased here.
                            if (token.parent.kind === 211 /* VariableDeclaration */ ||
                                token.parent.kind === 141 /* PropertyDeclaration */ ||
                                token.parent.kind === 138 /* Parameter */) {
                                return 5 /* operator */;
                            }
                        }
                        if (token.parent.kind === 181 /* BinaryExpression */ ||
                            token.parent.kind === 179 /* PrefixUnaryExpression */ ||
                            token.parent.kind === 180 /* PostfixUnaryExpression */ ||
                            token.parent.kind === 182 /* ConditionalExpression */) {
                            return 5 /* operator */;
                        }
                    }
                    return 10 /* punctuation */;
                }
                else if (tokenKind === 8 /* NumericLiteral */) {
                    return 4 /* numericLiteral */;
                }
                else if (tokenKind === 9 /* StringLiteral */) {
                    return 6 /* stringLiteral */;
                }
                else if (tokenKind === 10 /* RegularExpressionLiteral */) {
                    // TODO: we should get another classification type for these literals.
                    return 6 /* stringLiteral */;
                }
                else if (ts.isTemplateLiteralKind(tokenKind)) {
                    // TODO (drosen): we should *also* get another classification type for these literals.
                    return 6 /* stringLiteral */;
                }
                else if (tokenKind === 69 /* Identifier */) {
                    if (token) {
                        switch (token.parent.kind) {
                            case 214 /* ClassDeclaration */:
                                if (token.parent.name === token) {
                                    return 11 /* className */;
                                }
                                return;
                            case 137 /* TypeParameter */:
                                if (token.parent.name === token) {
                                    return 15 /* typeParameterName */;
                                }
                                return;
                            case 215 /* InterfaceDeclaration */:
                                if (token.parent.name === token) {
                                    return 13 /* interfaceName */;
                                }
                                return;
                            case 217 /* EnumDeclaration */:
                                if (token.parent.name === token) {
                                    return 12 /* enumName */;
                                }
                                return;
                            case 218 /* ModuleDeclaration */:
                                if (token.parent.name === token) {
                                    return 14 /* moduleName */;
                                }
                                return;
                            case 138 /* Parameter */:
                                if (token.parent.name === token) {
                                    return 17 /* parameterName */;
                                }
                                return;
                        }
                    }
                    return 2 /* identifier */;
                }
            }

function classifyTokenType ( tokenKind , token ) { if ( ts . isKeyword ( tokenKind ) ) { return 3 ; } if ( tokenKind === 25 || tokenKind === 27 ) { if ( token && ts . getTypeArgumentOrTypeParameterList ( token . parent ) ) { return 10 ; } } if ( ts . isPunctuation ( tokenKind ) ) { if ( token ) { if ( tokenKind === 56 ) { if ( token . parent . kind === 211 || token . parent . kind === 141 || token . parent . kind === 138 ) { return 5 ; } } if ( token . parent . kind === 181 || token . parent . kind === 179 || token . parent . kind === 180 || token . parent . kind === 182 ) { return 5 ; } } return 10 ; } else if ( tokenKind === 8 ) { return 4 ; } else if ( tokenKind === 9 ) { return 6 ; } else if ( tokenKind === 10 ) { return 6 ; } else if ( ts . isTemplateLiteralKind ( tokenKind ) ) { return 6 ; } else if ( tokenKind === 69 ) { if ( token ) { switch ( token . parent . kind ) { case 214 : if ( token . parent . name === token ) { return 11 ; } return ; case 137 : if ( token . parent . name === token ) { return 15 ; } return ; case 215 : if ( token . parent . name === token ) { return 13 ; } return ; case 217 : if ( token . parent . name === token ) { return 12 ; } return ; case 218 : if ( token . parent . name === token ) { return 14 ; } return ; case 138 : if ( token . parent . name === token ) { return 17 ; } return ; } } return 2 ; } }

for accurate classification, the actual token should be passed in.  however, for cases like 'disabled merge code' classification, we just get the token kind and classify based on that instead.

for accurate classification the actual token should be passed in . however for cases like disabled merge code classification we just get the token kind and classify based on that instead .


function getParametersFromRightHandSideOfAssignment(rightHandSide) {
            while (rightHandSide.kind === 172 /* ParenthesizedExpression */) {
                rightHandSide = rightHandSide.expression;
            }
            switch (rightHandSide.kind) {
                case 173 /* FunctionExpression */:
                case 174 /* ArrowFunction */:
                    return rightHandSide.parameters;
                case 186 /* ClassExpression */:
                    for (var _i = 0, _a = rightHandSide.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        if (member.kind === 144 /* Constructor */) {
                            return member.parameters;
                        }
                    }
                    break;
            }
            return emptyArray;
        }

Digs into an an initializer or RHS operand of an assignment operation
to get the parameters of an apt signature corresponding to a
function expression or a class expression.

@param rightHandSide the expression which may contain an appropriate set of parameters
@returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.

Digs into an an initializer or RHS operand of an assignment operation to get the parameters of an apt signature corresponding to a function expression or a class expression .


function score(backend, errorBasis) {
    if (typeof errorBasis !== "number" && !errorBasis)
        errorBasis = Date.now();
    const timeSinceError = (errorBasis - backend.lastError);
    const statuses = backend.statuses;
    const timeWeight = (backend.lastError === 0 && 0) ||
        ((timeSinceError < 1000) && 1) ||
        ((timeSinceError < 3000) && 0.8) ||
        ((timeSinceError < 5000) && 0.3) ||
        ((timeSinceError < 10000) && 0.1) ||
        0;
    if (statuses.length == 0)
        return 0;
    let requests = 0;
    let errors = 0;
    for (let i = 0; i < statuses.length; i++) {
        const status = statuses[i];
        if (status && !isNaN(status)) {
            requests += 1;
            if (status >= 500 && status < 600) {
                errors += 1;
            }
        }
    }
    const score = (1 - (timeWeight * (errors / requests)));
    backend.healthScore = score;
    backend.scoredRequestCount = backend.requestCount;
    return score;
}

function score ( backend , errorBasis ) { if ( typeof errorBasis !== "number" && ! errorBasis ) errorBasis = Date . now ( ) ; const timeSinceError = ( errorBasis - backend . lastError ) ; const statuses = backend . statuses ; const timeWeight = ( backend . lastError === 0 && 0 ) || ( ( timeSinceError < 1000 ) && 1 ) || ( ( timeSinceError < 3000 ) && 0.8 ) || ( ( timeSinceError < 5000 ) && 0.3 ) || ( ( timeSinceError < 10000 ) && 0.1 ) || 0 ; if ( statuses . length == 0 ) return 0 ; let requests = 0 ; let errors = 0 ; for ( let i = 0 ; i < statuses . length ; i ++ ) { const status = statuses [ i ] ; if ( status && ! isNaN ( status ) ) { requests += 1 ; if ( status >= 500 && status < 600 ) { errors += 1 ; } } } const score = ( 1 - ( timeWeight * ( errors / requests ) ) ) ; backend . healthScore = score ; backend . scoredRequestCount = backend . requestCount ; return score ; }

compute a backend health score with time + status codes


async function origin(req, init) {
  const url = new URL(req.url)
  const status = parseInt(url.searchParams.get('status') || '200')

  if (status === 200) {
    return new Response(`hello from ${req.url} on ${new Date()}`)
  } else {
    return new Response(`an error! Number ${status}`, { status: status })
  }
}

async function origin ( req , init ) { const url = new URL ( req . url ) const status = parseInt ( url . searchParams . get ( 'status' ) || '200' ) if ( status === 200 ) { return new Response ( ` ${ req . url } ${ new Date ( ) } ` ) } else { return new Response ( ` ${ status } ` , { status : status } ) } }

This is just a basic origin http server that
lets us control status codes.

`/` => successful response
`/?status=404` => serves a 404
`/?status=500` => serves a 500

This is just a basic origin http server that lets us control status codes .


function(element, transform, touch) {
          //
          // use translate both as basis for the new transform:
          //
          var t = $drag.TRANSLATE_BOTH(element, transform, touch);

          //
          // Add rotation:
          //
          var Dx = touch.distanceX;
          var t0 = touch.startTransform;
          var sign = Dx < 0 ? -1 : 1;
          var angle = sign * Math.min((Math.abs(Dx) / 700) * 30, 30);

          t.rotateZ = angle + (Math.round(t0.rotateZ));

          return t;
        }

function ( element , transform , touch ) { var t = $drag . TRANSLATE_BOTH ( element , transform , touch ) ; var Dx = touch . distanceX ; var t0 = touch . startTransform ; var sign = Dx < 0 ? - 1 : 1 ; var angle = sign * Math . min ( ( Math . abs ( Dx ) / 700 ) * 30 , 30 ) ; t . rotateZ = angle + ( Math . round ( t0 . rotateZ ) ) ; return t ; }

This is an example of custom transform function


function(t) {
        var absAngle = abs(t.angle);
        absAngle = absAngle >= 90 ? absAngle - 90 : absAngle;

        var validDistance = t.total - t.distance <= TURNAROUND_MAX;
        var validAngle = absAngle <= ANGLE_THRESHOLD || absAngle >= 90 - ANGLE_THRESHOLD;
        var validVelocity = t.averageVelocity >= VELOCITY_THRESHOLD;

        return validDistance && validAngle && validVelocity;
      }

function ( t ) { var absAngle = abs ( t . angle ) ; absAngle = absAngle >= 90 ? absAngle - 90 : absAngle ; var validDistance = t . total - t . distance <= TURNAROUND_MAX ; var validAngle = absAngle <= ANGLE_THRESHOLD || absAngle >= 90 - ANGLE_THRESHOLD ; var validVelocity = t . averageVelocity >= VELOCITY_THRESHOLD ; return validDistance && validAngle && validVelocity ; }

start to consider only if movement exceeded MOVEMENT_THRESHOLD


function(element, eventHandlers, options) {
        options = angular.extend({}, defaultOptions, options || {});
        return $touch.bind(element, eventHandlers, options);
      }

function ( element , eventHandlers , options ) { options = angular . extend ( { } , defaultOptions , options || { } ) ; return $touch . bind ( element , eventHandlers , options ) ; }

Bind swipe gesture handlers for an element.

``` js
var unbind = $swipe.bind(elem, {
end: function(touch) {
console.log('Swiped:', touch.direction);
unbind();
}
});
```

**Swipes Detection**

Before consider a touch to be a swipe Mobile Angular UI verifies that:

1. Movement is quick. Average touch velocity should exceed a `VELOCITY_THRESHOLD`.
2. Movement is linear.
3. Movement has a clear, non-ambiguous direction. So we can assume without error
that underlying `touch.direction` is exactly the swipe direction. For that
movement is checked against an `ANGLE_THRESHOLD`.

@param  {Element|$element} element The element to observe for swipe gestures.
@param  {object} eventHandlers An object with handlers for specific swipe events.
@param  {function} [eventHandlers.start]  The callback for swipe start event.
@param  {function} [eventHandlers.end]  The callback for swipe end event.
@param  {function} [eventHandlers.move]  The callback for swipe move event.
@param  {function} [eventHandlers.cancel]  The callback for swipe cancel event.
@param  {object} [options] Options to be passed to underlying [$touch.bind](../module:touch) function.

@returns {function} The unbind function.

@method bind
@memberOf mobile-angular-ui.gestures.swipe~$swipe

Bind swipe gesture handlers for an element .


function(type, c, t0, tl) {
      // Compute values for new TouchInfo based on coordinates and previus touches.
      // - c is coords of new touch
      // - t0 is first touch: useful to compute duration and distance (how far pointer
      //                    got from first touch)
      // - tl is last touch: useful to compute velocity and length (total length of the movement)

      t0 = t0 || {};
      tl = tl || {};

      // timestamps
      var ts = now();
      var ts0 = t0.timestamp || ts;
      var tsl = tl.timestamp || ts0;

      // coords
      var x = c.x;
      var y = c.y;
      var x0 = t0.x || x;
      var y0 = t0.y || y;
      var xl = tl.x || x0;
      var yl = tl.y || y0;

      // total movement
      var totalXl = tl.totalX || 0;
      var totalYl = tl.totalY || 0;
      var totalX = totalXl + abs(x - xl);
      var totalY = totalYl + abs(y - yl);
      var total = len(totalX, totalY);

      // duration
      var duration = timediff(ts, ts0);
      var durationl = timediff(ts, tsl);

      // distance
      var dxl = x - xl;
      var dyl = y - yl;
      var dl = len(dxl, dyl);
      var dx = x - x0;
      var dy = y - y0;
      var d = len(dx, dy);

      // velocity (px per second)
      var v = durationl > 0 ? abs(dl / (durationl / 1000)) : 0;
      var tv = duration > 0 ? abs(total / (duration / 1000)) : 0;

      // main direction: 'LEFT', 'RIGHT', 'TOP', 'BOTTOM'
      var dir = abs(dx) > abs(dy) ?
        (dx < 0 ? 'LEFT' : 'RIGHT') :
        (dy < 0 ? 'TOP' : 'BOTTOM');

      // angle (angle between distance vector and x axis)
      // angle will be:
      //   0 for x > 0 and y = 0
      //   90 for y < 0 and x = 0
      //   180 for x < 0 and y = 0
      //   -90 for y > 0 and x = 0
      //
      //               -90°
      //                |
      //                |
      //                |
      //   180° --------|-------- 0°
      //                |
      //                |
      //                |
      //               90°
      //
      var angle = dx !== 0 || dy !== 0 ? atan2(dy, dx) * (180 / Math.PI) : null;
      angle = angle === -180 ? 180 : angle;

      return {
        type: type,
        timestamp: ts,
        duration: duration,
        startX: x0,
        startY: y0,
        prevX: xl,
        prevY: yl,
        x: c.x,
        y: c.y,

        step: dl, // distance from prev
        stepX: dxl,
        stepY: dyl,

        velocity: v,
        averageVelocity: tv,

        distance: d, // distance from start
        distanceX: dx,
        distanceY: dy,

        total: total, // total length of momement,
        // considering turnaround
        totalX: totalX,
        totalY: totalY,
        direction: dir,
        angle: angle
      };
    }

function ( type , c , t0 , tl ) { t0 = t0 || { } ; tl = tl || { } ; var ts = now ( ) ; var ts0 = t0 . timestamp || ts ; var tsl = tl . timestamp || ts0 ; var x = c . x ; var y = c . y ; var x0 = t0 . x || x ; var y0 = t0 . y || y ; var xl = tl . x || x0 ; var yl = tl . y || y0 ; var totalXl = tl . totalX || 0 ; var totalYl = tl . totalY || 0 ; var totalX = totalXl + abs ( x - xl ) ; var totalY = totalYl + abs ( y - yl ) ; var total = len ( totalX , totalY ) ; var duration = timediff ( ts , ts0 ) ; var durationl = timediff ( ts , tsl ) ; var dxl = x - xl ; var dyl = y - yl ; var dl = len ( dxl , dyl ) ; var dx = x - x0 ; var dy = y - y0 ; var d = len ( dx , dy ) ; var v = durationl > 0 ? abs ( dl / ( durationl / 1000 ) ) : 0 ; var tv = duration > 0 ? abs ( total / ( duration / 1000 ) ) : 0 ; var dir = abs ( dx ) > abs ( dy ) ? ( dx < 0 ? 'LEFT' : 'RIGHT' ) : ( dy < 0 ? 'TOP' : 'BOTTOM' ) ; var angle = dx !== 0 || dy !== 0 ? atan2 ( dy , dx ) * ( 180 / Math . PI ) : null ; angle = angle === - 180 ? 180 : angle ; return { type : type , timestamp : ts , duration : duration , startX : x0 , startY : y0 , prevX : xl , prevY : yl , x : c . x , y : c . y , step : dl , stepX : dxl , stepY : dyl , velocity : v , averageVelocity : tv , distance : d , distanceX : dx , distanceY : dy , total : total , totalX : totalX , totalY : totalY , direction : dir , angle : angle } ; }

`TouchInfo` is an object containing the following extended informations about any touch
event.

@property {string} type Normalized event type. Despite of pointer device is always one of `touchstart`, `touchend`, `touchmove`, `touchcancel`.
@property {Date} timestamp The time object corresponding to the moment this touch event happened.
@property {integer} duration The difference between this touch event and the corresponding `touchstart`.
@property {float} startX X coord of related `touchstart`.
@property {float} startY Y coord of related `touchstart`.
@property {float} prevX X coord of previous `touchstart` or `touchmove`.
@property {float} prevY Y coord of previous `touchstart` or `touchmove`.
@property {float} x X coord of this touch event.
@property {float} y Y coord of this touch event.
@property {float} step Distance between `[prevX, prevY]` and `[x, y]` points.
@property {float} stepX Distance between `prevX` and `x`.
@property {float} stepY Distance between `prevY` and `y`.
@property {float} velocity Instantaneous velocity of a touch event in pixels per second.
@property {float} averageVelocity Average velocity of a touch event from its corresponding `touchstart` in pixels per second.
@property {float} distance Distance between `[startX, startY]` and `[x, y]` points.
@property {float} distanceX Distance between `startX` and `x`.
@property {float} distanceY Distance between `startY` and `y`.
@property {float} total Total number of pixels covered by movement, taking account of direction changes and turnarounds.
@property {float} totalX Total number of pixels covered by horizontal movement, taking account of direction changes and turnarounds.
@property {float} totalY Total number of pixels covered by vertical, taking account of direction changes and turnarounds.
@property {string} direction The current prevalent direction for this touch, one of `LEFT`, `RIGHT`, `TOP`, `BOTTOM`.
@property {float} angle Angle in degree between x axis and the vector `[x, y]`, is `null` when no movement happens.

@class TouchInfo
@ngdoc type
@memberOf mobile-angular-ui.gestures.touch~$touch

TouchInfo is an object containing the following extended informations about any touch event .


function(event) {
            // don't handle multi-touch
            if (event.touches && event.touches.length > 1) {
              return;
            }
            tl = t0 = buildTouchInfo('touchstart', getCoordinates(event));
            $movementTarget.on(moveEvents, onTouchMove);
            $movementTarget.on(endEvents, onTouchEnd);
            if (cancelEvents) {
              $movementTarget.on(cancelEvents, onTouchCancel);
            }
            if (startEventHandler) {
              startEventHandler(t0, event);
            }
          }

function ( event ) { if ( event . touches && event . touches . length > 1 ) { return ; } tl = t0 = buildTouchInfo ( 'touchstart' , getCoordinates ( event ) ) ; $movementTarget . on ( moveEvents , onTouchMove ) ; $movementTarget . on ( endEvents , onTouchEnd ) ; if ( cancelEvents ) { $movementTarget . on ( cancelEvents , onTouchCancel ) ; } if ( startEventHandler ) { startEventHandler ( t0 , event ) ; } }


function(e) {
      e = e.length ? e[0] : e;
      var tr = window
        .getComputedStyle(e, null)
        .getPropertyValue(transformProperty);
      return tr;
    }

function ( e ) { e = e . length ? e [ 0 ] : e ; var tr = window . getComputedStyle ( e , null ) . getPropertyValue ( transformProperty ) ; return tr ; }

return current element transform matrix in a cross-browser way

return current element transform matrix in a cross - browser way


function(elem, value) {
      elem = elem.length ? elem[0] : elem;
      elem.style[styleProperty] = value;
    }

function ( elem , value ) { elem = elem . length ? elem [ 0 ] : elem ; elem . style [ styleProperty ] = value ; }

set current element transform matrix in a cross-browser way

set current element transform matrix in a cross - browser way


function(e, t) {
        var str = (typeof t === 'string') ? t : this.toCss(t);
        setElementTransformProperty(e, str);
      }

function ( e , t ) { var str = ( typeof t === 'string' ) ? t : this . toCss ( t ) ; setElementTransformProperty ( e , str ) ; }

Recompose a transform from decomposition `t` and apply it to element `e`

Recompose a transform from decomposition t and apply it to element e


function (_path) {
  if (/^((pre|post)?loader)s?/ig.test(_path)) {
    return _path.replace(/^((pre|post)?loader)s?/ig, 'module.$1s')
  }

  if (/^(plugin)s?/g.test(_path)) {
    return _path.replace(/^(plugin)s?/g, '$1s')
  }

  return _path
}

function ( _path ) { if ( / ^((pre|post)?loader)s? / ig . test ( _path ) ) { return _path . replace ( / ^((pre|post)?loader)s? / ig , 'module.$1s' ) } if ( / ^(plugin)s? / g . test ( _path ) ) { return _path . replace ( / ^(plugin)s? / g , '$1s' ) } return _path }


function getPayload(token) {
  const payloadBase64 = token
    .split(".")[1]
    .replace("-", "+")
    .replace("_", "/");
  const payloadDecoded = base64.decode(payloadBase64);
  const payloadObject = JSON.parse(payloadDecoded);

  if (AV.isNumber(payloadObject.exp)) {
    payloadObject.exp = new Date(payloadObject.exp * 1000);
  }

  return payloadObject;
}

function getPayload ( token ) { const payloadBase64 = token . split ( "." ) [ 1 ] . replace ( "-" , "+" ) . replace ( "_" , "/" ) ; const payloadDecoded = base64 . decode ( payloadBase64 ) ; const payloadObject = JSON . parse ( payloadDecoded ) ; if ( AV . isNumber ( payloadObject . exp ) ) { payloadObject . exp = new Date ( payloadObject . exp * 1000 ) ; } return payloadObject ; }

Retrieves the payload from a JWT
@param  {String} token The JWT to retrieve the payload from
@return {Object}       The JWT payload


function setChapterActive($chapter, hash) {
    // No chapter and no hash means first chapter
    if (!$chapter && !hash) {
        $chapter = $chapters.first();
    }

    // If hash is provided, set as active chapter
    if (!!hash) {
        // Multiple chapters for this file
        if ($chapters.length > 1) {
            $chapter = $chapters.filter(function() {
                var titleId = getChapterHash($(this));
                return titleId == hash;
            }).first();
        }
        // Only one chapter, no need to search
        else {
            $chapter = $chapters.first();
        }
    }

    // Don't update current chapter
    if ($chapter.is($activeChapter)) {
        return;
    }

    // Update current active chapter
    $activeChapter = $chapter;

    // Add class to selected chapter
    $chapters.removeClass('active');
    $chapter.addClass('active');

    // Update history state if needed
    hash = getChapterHash($chapter);

    var oldUri = window.location.pathname + window.location.hash,
        uri = window.location.pathname + hash;

    if (uri != oldUri) {
        history.replaceState({ path: uri }, null, uri);
    }
}

function setChapterActive ( $chapter , hash ) { if ( ! $chapter && ! hash ) { $chapter = $chapters . first ( ) ; } if ( ! ! hash ) { if ( $chapters . length > 1 ) { $chapter = $chapters . filter ( function ( ) { var titleId = getChapterHash ( $ ( this ) ) ; return titleId == hash ; } ) . first ( ) ; } else { $chapter = $chapters . first ( ) ; } } if ( $chapter . is ( $activeChapter ) ) { return ; } $activeChapter = $chapter ; $chapters . removeClass ( 'active' ) ; $chapter . addClass ( 'active' ) ; hash = getChapterHash ( $chapter ) ; var oldUri = window . location . pathname + window . location . hash , uri = window . location . pathname + hash ; if ( uri != oldUri ) { history . replaceState ( { path : uri } , null , uri ) ; } }

Set a chapter as active in summary and update state


function getChapterHash($chapter) {
    var $link = $chapter.children('a'),
        hash = $link.attr('href').split('#')[1];

    if (hash) hash = '#'+hash;
    return (!!hash)? hash : '';
}

function getChapterHash ( $chapter ) { var $link = $chapter . children ( 'a' ) , hash = $link . attr ( 'href' ) . split ( '#' ) [ 1 ] ; if ( hash ) hash = '#' + hash ; return ( ! ! hash ) ? hash : '' ; }


function handleScrolling() {
    // Get current page scroll
    var $scroller      = getScroller(),
        scrollTop      = $scroller.scrollTop(),
        scrollHeight   = $scroller.prop('scrollHeight'),
        clientHeight   = $scroller.prop('clientHeight'),
        nbChapters     = $chapters.length,
        $chapter       = null;

    // Find each title position in reverse order
    $($chapters.get().reverse()).each(function(index) {
        var titleId = getChapterHash($(this)),
            titleTop;

        if (!!titleId && !$chapter) {
            titleTop = getElementTopPosition(titleId);

            // Set current chapter as active if scroller passed it
            if (scrollTop >= titleTop) {
                $chapter = $(this);
            }
        }
        // If no active chapter when reaching first chapter, set it as active
        if (index == (nbChapters - 1) && !$chapter) {
            $chapter = $(this);
        }
    });

    // ScrollTop is at 0, set first chapter anyway
    if (!$chapter && !scrollTop) {
        $chapter = $chapters.first();
    }

    // Set last chapter as active if scrolled to bottom of page
    if (!!scrollTop && (scrollHeight - scrollTop == clientHeight)) {
        $chapter = $chapters.last();
    }

    setChapterActive($chapter);
}

function handleScrolling ( ) { var $scroller = getScroller ( ) , scrollTop = $scroller . scrollTop ( ) , scrollHeight = $scroller . prop ( 'scrollHeight' ) , clientHeight = $scroller . prop ( 'clientHeight' ) , nbChapters = $chapters . length , $chapter = null ; $ ( $chapters . get ( ) . reverse ( ) ) . each ( function ( index ) { var titleId = getChapterHash ( $ ( this ) ) , titleTop ; if ( ! ! titleId && ! $chapter ) { titleTop = getElementTopPosition ( titleId ) ; if ( scrollTop >= titleTop ) { $chapter = $ ( this ) ; } } if ( index == ( nbChapters - 1 ) && ! $chapter ) { $chapter = $ ( this ) ; } } ) ; if ( ! $chapter && ! scrollTop ) { $chapter = $chapters . first ( ) ; } if ( ! ! scrollTop && ( scrollHeight - scrollTop == clientHeight ) ) { $chapter = $chapters . last ( ) ; } setChapterActive ( $chapter ) ; }


function insertAt(parent, selector, index, element) {
    var lastIndex = parent.children(selector).length;
    if (index < 0) {
        index = Math.max(0, lastIndex + 1 + index);
    }
    parent.append(element);

    if (index < lastIndex) {
        parent.children(selector).eq(index).before(parent.children(selector).last());
    }
}

function insertAt ( parent , selector , index , element ) { var lastIndex = parent . children ( selector ) . length ; if ( index < 0 ) { index = Math . max ( 0 , lastIndex + 1 + index ) ; } parent . append ( element ) ; if ( index < lastIndex ) { parent . children ( selector ) . eq ( index ) . before ( parent . children ( selector ) . last ( ) ) ; } }

Insert a jquery element at a specific position


function createDropdownMenu(dropdown) {
    var $menu = $('
', {
        'class': 'dropdown-menu',
        'html': '

'
    });

    if (typeof dropdown == 'string') {
        $menu.append(dropdown);
    } else {
        var groups = dropdown.map(function(group) {
            if ($.isArray(group)) return group;
            else return [group];
        });

        // Create buttons groups
        groups.forEach(function(group) {
            var $group = $('
', {
                'class': 'buttons'
            });
            var sizeClass = 'size-'+group.length;

            // Append buttons
            group.forEach(function(btn) {
                btn = $.extend({
                    text: '',
                    className: '',
                    onClick: defaultOnClick
                }, btn || {});

                var $btn = $('<button>', {
                    'class': 'button '+sizeClass+' '+btn.className,
                    'text': btn.text
                });
                $btn.click(btn.onClick);

                $group.append($btn);
            });

            $menu.append($group);
        });

    }

    return $menu;
}


function createButton(opts) {
    opts = $.extend({
        // Aria label for the button
        label: '',

        // Icon to show
        icon: '',

        // Inner text
        text: '',

        // Right or left position
        position: 'left',

        // Other class name to add to the button
        className: '',

        // Triggered when user click on the button
        onClick: defaultOnClick,

        // Button is a dropdown
        dropdown: null,

        // Position in the toolbar
        index: null,

        // Button id for removal
        id: generateId()
    }, opts || {});

    buttons.push(opts);
    updateButton(opts);

    return opts.id;
}

function createButton ( opts ) { opts = $ . extend ( { label : '' , icon : '' , text : '' , position : 'left' , className : '' , onClick : defaultOnClick , dropdown : null , index : null , id : generateId ( ) } , opts || { } ) ; buttons . push ( opts ) ; updateButton ( opts ) ; return opts . id ; }


function removeButton(id) {
    buttons = $.grep(buttons, function(button) {
        return button.id != id;
    });

    updateAllButtons();
}

function removeButton ( id ) { buttons = $ . grep ( buttons , function ( button ) { return button . id != id ; } ) ; updateAllButtons ( ) ; }


function removeButtons(ids) {
    buttons = $.grep(buttons, function(button) {
        return ids.indexOf(button.id) == -1;
    });

    updateAllButtons();
}

function removeButtons ( ids ) { buttons = $ . grep ( buttons , function ( button ) { return ids . indexOf ( button . id ) == - 1 ; } ) ; updateAllButtons ( ) ; }

Remove multiple buttons from an array of ids


function toggleSidebar(_state, animation) {
    if (gitbook.state != null && isOpen() == _state) return;
    if (animation == null) animation = true;

    gitbook.state.$book.toggleClass('without-animation', !animation);
    gitbook.state.$book.toggleClass('with-summary', _state);

    gitbook.storage.set('sidebar', isOpen());
}

function toggleSidebar ( _state , animation ) { if ( gitbook . state != null && isOpen ( ) == _state ) return ; if ( animation == null ) animation = true ; gitbook . state . $book . toggleClass ( 'without-animation' , ! animation ) ; gitbook . state . $book . toggleClass ( 'with-summary' , _state ) ; gitbook . storage . set ( 'sidebar' , isOpen ( ) ) ; }

Toggle sidebar with or withour animation