function replaceWith($rootElement, elementsToRemove, newNode) {
      var firstElementToRemove = elementsToRemove[0],
          removeCount = elementsToRemove.length,
          parent = firstElementToRemove.parentNode,
          i, ii;

      if ($rootElement) {
        for(i = 0, ii = $rootElement.length; i < ii; i++) {
          if ($rootElement[i] == firstElementToRemove) {
            $rootElement[i++] = newNode;
            for (var j = i, j2 = j + removeCount - 1,
                     jj = $rootElement.length;
                 j < jj; j++, j2++) {
              if (j2 < jj) {
                $rootElement[j] = $rootElement[j2];
              } else {
                delete $rootElement[j];
              }
            }
            $rootElement.length -= removeCount - 1;
            break;
          }
        }
      }

      if (parent) {
        parent.replaceChild(newNode, firstElementToRemove);
      }
      var fragment = document.createDocumentFragment();
      fragment.appendChild(firstElementToRemove);
      newNode[jqLite.expando] = firstElementToRemove[jqLite.expando];
      for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {
        var element = elementsToRemove[k];
        jqLite(element).remove(); // must do this way to clean up expando
        fragment.appendChild(element);
        delete elementsToRemove[k];
      }

      elementsToRemove[0] = newNode;
      elementsToRemove.length = 1
    }

function replaceWith ( $rootElement , elementsToRemove , newNode ) { var firstElementToRemove = elementsToRemove [ 0 ] , removeCount = elementsToRemove . length , parent = firstElementToRemove . parentNode , i , ii ; if ( $rootElement ) { for ( i = 0 , ii = $rootElement . length ; i < ii ; i ++ ) { if ( $rootElement [ i ] == firstElementToRemove ) { $rootElement [ i ++ ] = newNode ; for ( var j = i , j2 = j + removeCount - 1 , jj = $rootElement . length ; j < jj ; j ++ , j2 ++ ) { if ( j2 < jj ) { $rootElement [ j ] = $rootElement [ j2 ] ; } else { delete $rootElement [ j ] ; } } $rootElement . length -= removeCount - 1 ; break ; } } } if ( parent ) { parent . replaceChild ( newNode , firstElementToRemove ) ; } var fragment = document . createDocumentFragment ( ) ; fragment . appendChild ( firstElementToRemove ) ; newNode [ jqLite . expando ] = firstElementToRemove [ jqLite . expando ] ; for ( var k = 1 , kk = elementsToRemove . length ; k < kk ; k ++ ) { var element = elementsToRemove [ k ] ; jqLite ( element ) . remove ( ) ; fragment . appendChild ( element ) ; delete elementsToRemove [ k ] ; } elementsToRemove [ 0 ] = newNode ; elementsToRemove . length = 1 }

This is a special jqLite.replaceWith, which can replace items which
have no parents, provided that the containing jqLite collection is provided.

@param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes
in the root of the tree.
@param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep the shell,
but replace its DOM node reference.
@param {Node} newNode The new DOM node.

This is a special jqLite . replaceWith which can replace items which have no parents provided that the containing jqLite collection is provided .


function arrayDeclaration () {
    var elementFns = [];
    var allConstant = true;
    if (peekToken().text != ']') {
      do {
        var elementFn = expression();
        elementFns.push(elementFn);
        if (!elementFn.constant) {
          allConstant = false;
        }
      } while (expect(','));
    }
    consume(']');
    return extend(function(self, locals){
      var array = [];
      for ( var i = 0; i < elementFns.length; i++) {
        array.push(elementFns[i](self, locals));
      }
      return array;
    }, {
      literal:true,
      constant:allConstant
    });
  }

function arrayDeclaration ( ) { var elementFns = [ ] ; var allConstant = true ; if ( peekToken ( ) . text != ']' ) { do { var elementFn = expression ( ) ; elementFns . push ( elementFn ) ; if ( ! elementFn . constant ) { allConstant = false ; } } while ( expect ( ',' ) ) ; } consume ( ']' ) ; return extend ( function ( self , locals ) { var array = [ ] ; for ( var i = 0 ; i < elementFns . length ; i ++ ) { array . push ( elementFns [ i ] ( self , locals ) ) ; } return array ; } , { literal : true , constant : allConstant } ) ; }

This is used with json array declaration


function isSameOrigin(requestUrl) {
        var parsed = (typeof requestUrl === 'string') ? resolve(requestUrl, true) : requestUrl;
        return (parsed.protocol === originUrl.protocol &&
                parsed.host === originUrl.host);
      }

function isSameOrigin ( requestUrl ) { var parsed = ( typeof requestUrl === 'string' ) ? resolve ( requestUrl , true ) : requestUrl ; return ( parsed . protocol === originUrl . protocol && parsed . host === originUrl . host ) ; }

Parse a request URL and determine whether this is a same-origin request as the application document.

@param {string|object} requestUrl The url of the request as a string that will be resolved
or a parsed URL object.
@returns {boolean} Whether the request is for the same origin as the application document.

Parse a request URL and determine whether this is a same - origin request as the application document .


function traverse(node, opt_onEnter, opt_onLeave) {
  if (opt_onEnter) opt_onEnter(node);

  var childNodes = _collectChildNodes(node);
  childNodes.forEach(function(childNode) {
    traverse(childNode, opt_onEnter, opt_onLeave);
  });

  if (opt_onLeave) opt_onLeave(node);
}

function traverse ( node , opt_onEnter , opt_onLeave ) { if ( opt_onEnter ) opt_onEnter ( node ) ; var childNodes = _collectChildNodes ( node ) ; childNodes . forEach ( function ( childNode ) { traverse ( childNode , opt_onEnter , opt_onLeave ) ; } ) ; if ( opt_onLeave ) opt_onLeave ( node ) ; }

Traverse the specified AST.
@param {{ type: NodeType }} node AST to traverse.
@param {function({ type: NodeType })?} opt_onEnter Callback for onEnter.
@param {function({ type: NodeType })?} opt_onLeave Callback for onLeave.


function Client() {

    logger('new Client');
    this.type = 'client';
    this.id = uuid();
    this.browser = (WebSocket.Server === undefined);
    Base.call(this);
  }

function
Client
(
)
{
logger
(
'new Client'
)
;
this
.
type
=
'client'
;
this
.
id
=
uuid
(
)
;
this
.
browser
=
(
WebSocket
.
Server
===
undefined
)
;
Base
.
call
(
this
)
;
}

json-rpc-ws client

@param {Object} Parent object, used to find method handlers.
@param {Socket} WebSocket connection.
@extends {Base}
@constructor


function Connection(socket, parent) {

  logger('new Connection to %s', parent.type);
  this.id = uuid();
  this.socket = socket;
  this.parent = parent;
  this.responseHandlers = {};
  if (this.parent.browser) {
    this.socket.onmessage = this.message.bind(this);
    this.socket.onclose = socketClosed.bind(this);
    this.socket.onerror = socketError.bind(this);
  }
  else {
    this.socket.on('message', this.message.bind(this));
    this.socket.once('close', this.close.bind(this));
    this.socket.once('error', this.close.bind(this));
  }
}

function
Connection
(
socket
,
parent
)
{
logger
(
'new Connection to %s'
,
parent
.
type
)
;
this
.
id
=
uuid
(
)
;
this
.
socket
=
socket
;
this
.
parent
=
parent
;
this
.
responseHandlers
=
{
}
;
if
(
this
.
parent
.
browser
)
{
this
.
socket
.
onmessage
=
this
.
message
.
bind
(
this
)
;
this
.
socket
.
onclose
=
socketClosed
.
bind
(
this
)
;
this
.
socket
.
onerror
=
socketError
.
bind
(
this
)
;
}
else
{
this
.
socket
.
on
(
'message'
,
this
.
message
.
bind
(
this
)
)
;
this
.
socket
.
once
(
'close'
,
this
.
close
.
bind
(
this
)
)
;
this
.
socket
.
once
(
'error'
,
this
.
close
.
bind
(
this
)
)
;
}
}

json-rpc-ws connection

@constructor
@param {Socket} socket - web socket for this connection
@param {Object} parent - parent that controls this connection


function mark(type, attrs) {
  return function(...args) {
    let mark = type.create(takeAttrs(attrs, args))
    let {nodes, tag} = flatten(type.schema, args, n => mark.type.isInSet(n.marks) ? n : n.mark(mark.addToSet(n.marks)))
    return {flat: nodes, tag}
  }
}

function mark ( type , attrs ) { return function ( ... args ) { let mark = type . create ( takeAttrs ( attrs , args ) ) let { nodes , tag } = flatten ( type . schema , args , n => mark . type . isInSet ( n . marks ) ? n : n . mark ( mark . addToSet ( n . marks ) ) ) return { flat : nodes , tag } } }


function serverRequest(config) {
                var defer = $q.defer();
                if (provider.debug) $log.info('$sails ' + config.method + ' ' + config.url, config.data || '');

                if (config.timeout > 0) {
                    $timeout(timeoutRequest, config.timeout);
                } else if (isPromiseLike(config.timeout)) {
                    config.timeout.then(timeoutRequest);
                }

                socket['legacy_' + config.method.toLowerCase()](config.url, config.data, serverResponse);

                function timeoutRequest(){
                    serverResponse(null);
                }

                function serverResponse(result, jwr) {

                    if (!jwr) {
                        jwr = {
                            body: result,
                            headers: result.headers || {},
                            statusCode: result.statusCode || result.status || 0,
                            error: (function() {
                                if (this.statusCode < 200 || this.statusCode >= 400) {
                                    return this.body || this.statusCode;
                                }
                            })()
                        };
                    }

                    jwr.data = jwr.body; // $http compat
                    jwr.status = jwr.statusCode; // $http compat
                    jwr.socket = socket;
                    jwr.url = config.url;
                    jwr.method = config.method;
                    jwr.config = config.config;
                    if (jwr.error) {
                        if (provider.debug) $log.warn('$sails response ' + jwr.statusCode + ' ' + config.url, jwr);
                        defer.reject(jwr);
                    } else {
                        if (provider.debug) $log.info('$sails response ' + config.url, jwr);
                        defer.resolve(jwr);
                    }
                }

                return defer.promise;
            }

function
serverRequest
(
config
)
{
var
defer
=
$q
.
defer
(
)
;
if
(
provider
.
debug
)
$log
.
info
(
'$sails '
+
config
.
method
+
' '
+
config
.
url
,
config
.
data
||
''
)
;
if
(
config
.
timeout
>
0
)
{
$timeout
(
timeoutRequest
,
config
.
timeout
)
;
}
else
if
(
isPromiseLike
(
config
.
timeout
)
)
{
config
.
timeout
.
then
(
timeoutRequest
)
;
}
socket
[
'legacy_'
+
config
.
method
.
toLowerCase
(
)
]
(
config
.
url
,
config
.
data
,
serverResponse
)
;
function
timeoutRequest
(
)
{
serverResponse
(
)
;
}
function
serverResponse
(
result
,
jwr
)
{
if
(
!
jwr
)
{
jwr
=
{
body
:
result
,
headers
:
result
.
headers
||
{
}
,
statusCode
:
result
.
statusCode
||
result
.
status
||
0
,
error
:
(
function
(
)
{
if
(
this
.
statusCode
<
200
||
this
.
statusCode
>=
400
)
{
return
this
.
body
||
this
.
statusCode
;
}
}
)
(
)
}
;
}
jwr
.
data
=
jwr
.
body
;
jwr
.
status
=
jwr
.
statusCode
;
jwr
.
socket
=
socket
;
jwr
.
url
=
config
.
url
;
jwr
.
method
=
config
.
method
;
jwr
.
config
=
config
.
config
;
if
(
jwr
.
error
)
{
if
(
provider
.
debug
)
$log
.
warn
(
'$sails response '
+
jwr
.
statusCode
+
' '
+
config
.
url
,
jwr
)
;
defer
.
reject
(
jwr
)
;
}
else
{
if
(
provider
.
debug
)
$log
.
info
(
'$sails response '
+
config
.
url
,
jwr
)
;
defer
.
resolve
(
jwr
)
;
}
}
return
defer
.
promise
;
}


function processBootStrap(file) {
    var data = fs.readFileSync(file).toString();
    var idx = data.indexOf('bootstrap(');
    if (idx === -1) { return null; }
    else { idx+=10; }

    var odx1 = data.indexOf(',', idx);
    var odx2 = data.indexOf(')', idx);
    if (odx2 < odx1 && odx2 !== -1 || odx1 === -1) { odx1 = odx2; }
    if (odx1 === -1) { return null; }
    var componentRef = data.substring(idx, odx1);
    var exp = "import\\s+\\{("+componentRef+")\\}\\s+from+\\s+[\'|\"](\\S+)[\'|\"][;?]";
    if (debugging) {
        console.log("Searching for", exp);
    }

    var result = function (r) {
      return {
        name: r[1],
        path: r[r.length - 1]
      };
    };
    //noinspection JSPotentiallyInvalidConstructorUsage
    var r = RegExp(exp, 'i').exec(data);
    if (r === null || r.length <= 1) {
      // check if using current style guide with spaces
      exp = "import\\s+\\{\\s+("+componentRef+")\\,\\s+([A-Z]{0,300})\\w+\\s+\\}\\s+from+\\s+[\'|\"](\\S+)[\'|\"][;?]";
      if (debugging) {
        console.log("Searching for", exp);
      }
      r = RegExp(exp, 'i').exec(data);
      if (r === null || r.length <= 1) {
        // try just spaces with no angular cli style (, environment) etc.
        exp = "import\\s+\\{\\s+(" + componentRef + ")\\s+\\}\\s+from+\\s+[\'|\"](\\S+)[\'|\"][;?]";
        if (debugging) {
          console.log("Searching for", exp);
        }
        r = RegExp(exp, 'i').exec(data);
        if (r !== null && r.length > 1) {
          return result(r);
        }
      } else {
        // angular cli
        return result(r);
      }
      return null;
    }
    return result(r);
}

Parses the bootstrap to figure out the default bootstrap component
@param file
@returns {*}


function fixTsConfig() {
    var tsConfig={}, tsFile = '../../tsconfig.json';
    if (fs.existsSync(tsFile)) {
        tsConfig = require(tsFile);
    }
    if (!tsConfig.compilerOptions || !tsConfig.compilerOptions.typeRoots) {
        tsConfig.compilerOptions = {
          target: "es5",
          module: "commonjs",
          declaration: false,
          removeComments: true,
          noLib: false,
          emitDecoratorMetadata: true,
          experimentalDecorators: true,
          lib: [
            "dom"
          ],
          sourceMap: true,
          pretty: true,
          allowUnreachableCode: false,
          allowUnusedLabels: false,
          noImplicitAny: false,
          noImplicitReturns: true,
          noImplicitUseStrict: false,
          noFallthroughCasesInSwitch: true,
          typeRoots: [
              "node_modules/@types",
              "node_modules"
          ],
          types: [
              "jasmine"
          ]
        };
    }

    // See: https://github.com/NativeScript/nativescript-angular/issues/205
    // tsConfig.compilerOptions.noEmitHelpers = false;
    // tsConfig.compilerOptions.noEmitOnError = false;

    if (!tsConfig.exclude) {
        tsConfig.exclude = [];
    }
    if (tsConfig.exclude.indexOf('node_modules') === -1) {
        tsConfig.exclude.push('node_modules');
    }
    if (tsConfig.exclude.indexOf('platforms') === -1) {
        tsConfig.exclude.push('platforms');
    }

    fs.writeFileSync(tsFile, JSON.stringify(tsConfig, null, 4), 'utf8');
}

function fixTsConfig ( ) { var tsConfig = { } , tsFile = '../../tsconfig.json' ; if ( fs . existsSync ( tsFile ) ) { tsConfig = require ( tsFile ) ; } if ( ! tsConfig . compilerOptions || ! tsConfig . compilerOptions . typeRoots ) { tsConfig . compilerOptions = { target : "es5" , module : "commonjs" , declaration : false , removeComments : true , noLib : false , emitDecoratorMetadata : true , experimentalDecorators : true , lib : [ "dom" ] , sourceMap : true , pretty : true , allowUnreachableCode : false , allowUnusedLabels : false , noImplicitAny : false , noImplicitReturns : true , noImplicitUseStrict : false , noFallthroughCasesInSwitch : true , typeRoots : [ "node_modules/@types" , "node_modules" ] , types : [ "jasmine" ] } ; } if ( ! tsConfig . exclude ) { tsConfig . exclude = [ ] ; } if ( tsConfig . exclude . indexOf ( 'node_modules' ) === - 1 ) { tsConfig . exclude . push ( 'node_modules' ) ; } if ( tsConfig . exclude . indexOf ( 'platforms' ) === - 1 ) { tsConfig . exclude . push ( 'platforms' ) ; } fs . writeFileSync ( tsFile , JSON . stringify ( tsConfig , null , 4 ) , 'utf8' ) ; }

This fixes the TS Config file in the nativescript folder


function fixRefFile() {
    var existingRef='', refFile = '../../references.d.ts';
    if (fs.existsSync(refFile)) {
        existingRef = fs.readFileSync(refFile).toString();
    }

  if (existingRef.indexOf('typescript/lib/lib.d.ts') === -1) {
    // has not been previously modified
    var fix = '/// <reference path="./node_modules/tns-core-modules/tns-core-modules.d.ts" />\n' +
      '/// <reference path="./node_modules/typescript/lib/lib.d.ts" />\n';

    fs.writeFileSync(refFile, fix, 'utf8');
  }
}

This fixes the references file to work with TS 2.0 in the nativescript folder

This fixes the references file to work with TS 2 . 0 in the nativescript folder


function fixNativeScriptPackage() {
    var packageJSON = {}, packageFile = '../../package.json';
    packageJSON.name = "NativeScriptApp";
    packageJSON.version = "0.0.0";

    // var AngularJSON = {};
    if (fs.existsSync(packageFile)) {
        packageJSON = require(packageFile);
    } else {
        console.log("This should not happen, your are missing your package.json file!");
        return;
    }
    // if (fs.existsSync('../angular2/package.json')) {
    //     AngularJSON = require('../angular2/package.json');
    // } else {
    //     // Copied from the Angular2.0.0-beta-16 package.json, this is a fall back
    //     AngularJSON.peerDependencies = {
    //         "es6-shim": "^0.35.0",
    //         "reflect-metadata": "0.1.2",
    //         "rxjs": "5.0.0-beta.6",
    //         "zone.js": "^0.6.12"
    //     };
    // }

    packageJSON.nativescript['tns-ios'] = { version: "2.3.0" };
    packageJSON.nativescript['tns-android'] = {version: "2.3.0" };

    // Copy over all the Peer Dependencies
    // for (var key in AngularJSON.peerDependencies) {
    //     if (AngularJSON.peerDependencies.hasOwnProperty(key)) {
    //         packageJSON.dependencies[key] = AngularJSON.peerDependencies[key];
    //     }
    // }

    // TODO: Can we get these from somewhere rather than hardcoding them, maybe need to pull/download the package.json from the default template?
    if (!packageJSON.devDependencies) {
        packageJSON.devDependencies = {};
    }
    packageJSON.devDependencies["@types/jasmine"] = "^2.5.35";
    packageJSON.devDependencies["babel-traverse"] = "6.12.0";
    packageJSON.devDependencies["babel-types"] = "6.11.1";
    packageJSON.devDependencies.babylon = "6.8.4";
    packageJSON.devDependencies.filewalker = "0.1.2";
    packageJSON.devDependencies.lazy = "1.0.11";
    // packageJSON.devDependencies["nativescript-dev-typescript"] = "^0.3.2";
    packageJSON.devDependencies.typescript = "^2.0.2";

    fs.writeFileSync(packageFile, JSON.stringify(packageJSON, null, 4), 'utf8');
}


function fixAngularPackage() {
    var packageJSON = {}, packageFile = '../../../package.json';
    if (fs.existsSync(packageFile)) {
        packageJSON = require(packageFile);
    } else {
        console.log("This should not happen, your are missing your main package.json file!");
        return;
    }

    if (!packageJSON.scripts) {
        packageJSON.scripts = {};
    }

    packageJSON.scripts["start.ios"] = "cd nativescript && tns emulate ios";
    packageJSON.scripts["start.livesync.ios"] = "cd nativescript && tns livesync ios --emulator --watch";
    packageJSON.scripts["start.android"] = "cd nativescript && tns emulate android";
    packageJSON.scripts["start.livesync.android"] = "cd nativescript && tns livesync android --emulator --watch";

    fs.writeFileSync(packageFile, JSON.stringify(packageJSON, null, 4), 'utf8');
}


function fixMainFile(component) {
  var mainTS = '', mainFile = '../../app/main.ts';
  if (fs.existsSync(mainFile)) {
    mainTS = fs.readFileSync(mainFile).toString();
  }

  if (mainTS.indexOf('MagicService') === -1) {
    // has not been previously modified
    var fix = '// this import should be first in order to load some required settings (like globals and reflect-metadata)\n' +
      'import { platformNativeScriptDynamic, NativeScriptModule } from "nativescript-angular/platform";\n' +
      'import { NgModule } from "@angular/core";\n' +
      'import { AppComponent } from "./app/app.component";\n' +
      '\n' +
      '@NgModule({\n' +
      '  declarations: [AppComponent],\n' +
      '  bootstrap: [AppComponent],\n' +
      '   imports: [NativeScriptModule],\n' +
      '})\n' +
      'class AppComponentModule {}\n\n' +
      'platformNativeScriptDynamic().bootstrapModule(AppComponentModule);';

    fs.writeFileSync(mainFile, fix, 'utf8');
  }
}

Fix the Main NativeScript File
@param component


function fixGitIgnore(ignorePattern) {
  var fileString = '', ignoreFile = '../../../.gitignore';
  if (fs.existsSync(ignoreFile)) {
    fileString = fs.readFileSync(ignoreFile).toString();
  }

  if (fileString.indexOf(ignorePattern) === -1) {
    // has not been previously modified
    var fix = fileString +
      '\n' +
      ignorePattern;

    fs.writeFileSync(ignoreFile, fix, 'utf8');
  }
}

function fixGitIgnore ( ignorePattern ) { var fileString = '' , ignoreFile = '../../../.gitignore' ; if ( fs . existsSync ( ignoreFile ) ) { fileString = fs . readFileSync ( ignoreFile ) . toString ( ) ; } if ( fileString . indexOf ( ignorePattern ) === - 1 ) { var fix = fileString + '\n' + \n ; ignorePattern } }


function displayFinalHelp()
{
    console.log("-------------- Welcome to the Magical World of NativeScript -----------------------------");
    console.log("To finish, follow this guide https://github.com/NathanWalker/nativescript-ng2-magic#usage");
    console.log("After you have completed the steps in the usage guide, you can then:");
    console.log("");
    console.log("Run your app in the iOS Simulator with these options:");
    console.log("  npm run start.ios");
    console.log("  npm run start.livesync.ios");
    console.log("");
    console.log("Run your app in an Android emulator with these options:");
    console.log("  npm run start.android");
    console.log("  npm run start.livesync.android");
    console.log("-----------------------------------------------------------------------------------------");
    console.log("");
}


function bind(func, thisObject, var_args)
{
    var args = slice(arguments, 2);

    /**
     * @param {...} var_args
     */
    function bound(var_args)
    {
        return InjectedScriptHost.callFunction(func, thisObject, concat(args, slice(arguments)));
    }
    bound.toString = function()
    {
        return "bound: " + toString(func);
    };
    return bound;
}

function
bind
(
func
,
thisObject
,
var_args
)
{
var
args
=
slice
(
arguments
,
2
)
;
function
bound
(
var_args
)
{
return
InjectedScriptHost
.
callFunction
(
func
,
thisObject
,
concat
(
args
,
slice
(
arguments
)
)
)
;
}
bound
.
toString
=
function
(
)
{
return
"bound: "
+
toString
(
func
)
;
}
;
return
bound
;
}

Please use this bind, not the one from Function.prototype
@param {function(...)} func
@param {?Object} thisObject
@param {...} var_args
@return {function(...)}

Please use this bind not the one from Function . prototype


function(object, objectGroupName, forceValueType, generatePreview, columnNames, isTable, doNotBind, customObjectConfig)
    {
        try {
            return new InjectedScript.RemoteObject(object, objectGroupName, doNotBind, forceValueType, generatePreview, columnNames, isTable, undefined, customObjectConfig);
        } catch (e) {
            try {
                var description = injectedScript._describe(e);
            } catch (ex) {
                var description = "<failed to convert exception to string>";
            }
            return new InjectedScript.RemoteObject(description);
        }
    }

This method cannot throw.
@param {*} object
@param {string=} objectGroupName
@param {boolean=} forceValueType
@param {boolean=} generatePreview
@param {?Array.<string>=} columnNames
@param {boolean=} isTable
@param {boolean=} doNotBind
@param {*=} customObjectConfig
@return {!RuntimeAgent.RemoteObject}
@suppress {checkTypes}


function(callArgumentJson)
    {
        callArgumentJson = nullifyObjectProto(callArgumentJson);
        var objectId = callArgumentJson.objectId;
        if (objectId) {
            var parsedArgId = this._parseObjectId(objectId);
            if (!parsedArgId || parsedArgId["injectedScriptId"] !== injectedScriptId)
                throw "Arguments should belong to the same JavaScript world as the target object.";

            var resolvedArg = this._objectForId(parsedArgId);
            if (!this._isDefined(resolvedArg))
                throw "Could not find object with given id";

            return resolvedArg;
        } else if ("value" in callArgumentJson) {
            var value = callArgumentJson.value;
            if (callArgumentJson.type === "number" && typeof value !== "number")
                value = Number(value);
            return value;
        }
        return undefined;
    }

Resolves a value from CallArgument description.
@param {!RuntimeAgent.CallArgument} callArgumentJson
@return {*} resolved value
@throws {string} error message

Resolves a value from CallArgument description .


function(topCallFrame, callFrameId, functionObjectId, scopeNumber, variableName, newValueJsonString)
    {
        try {
            var newValueJson = /** @type {!RuntimeAgent.CallArgument} */ (InjectedScriptHost.eval("(" + newValueJsonString + ")"));
            var resolvedValue = this._resolveCallArgument(newValueJson);
            if (typeof callFrameId === "string") {
                var callFrame = this._callFrameForId(topCallFrame, callFrameId);
                if (!callFrame)
                    return "Could not find call frame with given id";
                callFrame.setVariableValue(scopeNumber, variableName, resolvedValue)
            } else {
                var parsedFunctionId = this._parseObjectId(/** @type {string} */ (functionObjectId));
                var func = this._objectForId(parsedFunctionId);
                if (typeof func !== "function")
                    return "Could not resolve function by id";
                InjectedScriptHost.setFunctionVariableValue(func, scopeNumber, variableName, resolvedValue);
            }
        } catch (e) {
            return toString(e);
        }
        return undefined;
    }

Either callFrameId or functionObjectId must be specified.
@param {!JavaScriptCallFrame} topCallFrame
@param {string|boolean} callFrameId or false
@param {string|boolean} functionObjectId or false
@param {number} scopeNumber
@param {string} variableName
@param {string} newValueJsonString RuntimeAgent.CallArgument structure serialized as string
@return {string|undefined} undefined if success or an error message

Either callFrameId or functionObjectId must be specified .


function validate(str) {
    let tj;

    if (typeof str === 'object') {
        tj = str;
    } else if (typeof str === 'string') {
        try {
            tj = jsonlint.parse(str);
        } catch (err) {
            return false;
        }
    } else {
        return false;
    }

    return tilejsonValidateObject.validate(tj);
}

function validate ( str ) { let tj ; if ( typeof str === 'object' ) { tj = str ; } else if ( typeof str === 'string' ) { try { tj = jsonlint . parse ( str ) ; } catch ( err ) { return false ; } } else { return false ; } return tilejsonValidateObject . validate ( tj ) ; }

Validates a TileJSON
@param {(string|object)} TileJSON as string or object
@returns {boolean} true if the validation is successful, false otherwise


function _loop2(_name) {
      var klass = resolve(associations[_name].klass);
      var data = associated[_name];

      // clear association
      if (!data) {
        model[_name] = null;
        return "continue";
      }

      if (associations[_name].type === 'hasOne') {
        var other = (typeof data === "undefined" ? "undefined" : _typeof(data)) === 'object' ? klass.load(data) : klass.local(data);
        model[_name] = other;
      } else if (associations[_name].type === 'hasMany') {
        var others = [];
        data.forEach(function (o) {
          others.push((typeof o === "undefined" ? "undefined" : _typeof(o)) === 'object' ? klass.load(o) : klass.local(o));
        });
        model[_name] = others;
      }
    }

function _loop2 ( _name ) { var klass = resolve ( associations [ _name ] . klass ) ; var data = associated [ _name ] ; if ( ! data ) { model [ _name ] = null ; return "continue" ; } if ( associations [ _name ] . type === 'hasOne' ) { var other = ( typeof data === "undefined" ? "undefined" : _typeof ( data ) ) === 'object' ? klass . load ( data ) : klass . local ( data ) ; model [ _name ] = other ; } else if ( associations [ _name ] . type === 'hasMany' ) { var others = [ ] ; data . forEach ( function ( o ) { others . push ( ( typeof o === "undefined" ? "undefined" : _typeof ( o ) ) === 'object' ? klass . load ( o ) : klass . local ( o ) ) ; } ) ; model [ _name ] = others ; } }


function handleErrors(errors, data) {
  const message = errors[0].message;
  const error = new Error(`GraphQL Error: ${message}`);
  error.rawError = errors;
  error.rawData = data;
  throw error;
}

function handleErrors ( errors , data ) { const message = errors [ 0 ] . message ; const error = new Error ( ` ${ message } ` ) ; error . rawError = errors ; error . rawData = data ; throw error ; }


function zip(zipFile, srcList, dstPath) {
  if (!dstPath) {
    dstPath = false;
  }
  const output = fs.createWriteStream(zipFile);
  const archive = archiver('zip', {
    zlib: { level: 9 } // Sets the compression level.
  });

  return new Promise((resolve, reject) => {
    output.on('close', function() {
      return resolve();
    });

    archive.on('warning', function(err) {
      if (err.code === 'ENOENT') {
        console.log(err);
      }
      else {
        return reject(err);
      }
    });

    archive.on('error', function(err) {
      return reject(err);
    });

    archive.pipe(output);

    srcList.forEach((src) => {
      const stat = fs.lstatSync(src);

      if (stat.isFile()) {
        archive.file(src);
      }
      else if (stat.isDirectory() || stat.isSymbolicLink()) {
        archive.directory(src, dstPath);
      }
      else {
        return reject(new Error('Invalid path'));
      }
    });

    archive.finalize();
  });
}

function
zip
(
zipFile
,
srcList
,
dstPath
)
{
if
(
!
dstPath
)
{
dstPath
=
false
;
}
const
output
=
fs
.
createWriteStream
(
zipFile
)
;
const
archive
=
archiver
(
'zip'
,
{
zlib
:
{
level
:
9
}
}
)
;
return
new
Promise
(
(
resolve
,
reject
)
=>
{
output
.
on
(
'close'
,
function
(
)
{
return
resolve
(
)
;
}
)
;
archive
.
on
(
'warning'
,
function
(
err
)
{
if
(
err
.
code
===
'ENOENT'
)
{
console
.
log
(
err
)
;
}
else
{
return
reject
(
err
)
;
}
}
)
;
archive
.
on
(
'error'
,
function
(
err
)
{
return
reject
(
err
)
;
}
)
;
archive
.
pipe
(
output
)
;
srcList
.
forEach
(
(
src
)
=>
{
const
stat
=
fs
.
lstatSync
(
src
)
;
if
(
stat
.
isFile
(
)
)
{
archive
.
file
(
src
)
;
}
else
if
(
stat
.
isDirectory
(
)
||
stat
.
isSymbolicLink
(
)
)
{
archive
.
directory
(
src
,
dstPath
)
;
}
else
{
return
reject
(
new
Error
(
'Invalid path'
)
)
;
}
}
)
;
archive
.
finalize
(
)
;
}
)
;
}

Zips a list of files or directories
@param  {string} zipFile filename and path where the zip file is stored
@param  {array} srcList array of files and directories paths
@param  {type} dstPath for directories whether to put the directories at
root of the zip file or relative to your path on the local machine
@return {Promise}


function exec(cmd, verbose) {
  verbose = verbose === false ? verbose : true;

  const stdout = execSync(cmd);
  if (verbose) {
    console.log(stdout.toString());
  }
  return stdout;
}

function exec ( cmd , verbose ) { verbose = verbose === false ? verbose : true ; const stdout = execSync ( cmd ) ; if ( verbose ) { console . log ( stdout . toString ( ) ) ; } return stdout ; }

Executes shell commands synchronously and logs the
stdout to console.
@param {String} cmd  Bash command
@param {Boolean} [verbose=true] whether to post stdout to console
@return {Buffer} The command's stdout in for of Buffer

Executes shell commands synchronously and logs the stdout to console .


function fileToString(file) {
  try {
    const stat = fs.lstatSync(file);

    if (stat.isFile()) {
      const content = fs.readFileSync(file, 'utf8');
      return content.toString();
    }
  }
  catch (e) {
    if (!e.message.includes('ENOENT') && !e.message.includes('name too long, lstat')) {
      throw e;
    }
  }
  return file;
}

function
fileToString
(
file
)
{
try
{
const
stat
=
fs
.
lstatSync
(
file
)
;
if
(
stat
.
isFile
(
)
)
{
const
content
=
fs
.
readFileSync
(
file
,
'utf8'
)
;
return
content
.
toString
(
)
;
}
}
catch
(
e
)
{
if
(
!
e
.
message
.
includes
(
'ENOENT'
)
&&
!
e
.
message
.
includes
(
'name too long, lstat'
)
)
{
throw
e
;
}
}
return
file
;
}

Checks if the input is a file, if it is a file,
it reads it and return the content, otherwise just pass
the input as an output

@param {String} file A file path or a string
@returns {String} String content of a given file

Checks if the input is a file if it is a file it reads it and return the content otherwise just pass the input as an output


function mergeYamls(file1, file2) {
  const obj1 = yaml.safeLoad(fileToString(file1), { schema: yamlfiles.YAML_FILES_SCHEMA });
  const obj2 = yaml.safeLoad(fileToString(file2), { schema: yamlfiles.YAML_FILES_SCHEMA });

  return yaml.safeDump(merge({}, obj1, obj2));
}

function mergeYamls ( file1 , file2 ) { const obj1 = yaml . safeLoad ( fileToString ( file1 ) , { schema : yamlfiles . YAML_FILES_SCHEMA } ) ; const obj2 = yaml . safeLoad ( fileToString ( file2 ) , { schema : yamlfiles . YAML_FILES_SCHEMA } ) ; return yaml . safeDump ( merge ( { } , obj1 , obj2 ) ) ; }

Merges two yaml files. The merge is done using lodash.merge
and it happens recursively. Meaning that values of file2 will
replace values of file 1 if they have the same key.

@param {String} file1 Yaml path to file 1 or file 1 string
@param {String} file2 Yaml path to file 2 or file 2 string
@returns {String} Merged Yaml file in string format

Merges two yaml files . The merge is done using lodash . merge and it happens recursively . Meaning that values of file2 will replace values of file 1 if they have the same key .


function loadKesOverride(kesFolder, kesClass = 'kes.js') {
  let kesOverridePath = path.resolve(kesFolder, kesClass);
  let KesOverride;

  try {
    KesOverride = require(kesOverridePath);
  }
  catch (e) {
    // If the Kes override file exists, then the error occured when
    // trying to parse the file, so re-throw and prevent Kes from
    // going further.
    const fileExists = fs.existsSync(kesOverridePath);
    if (fileExists) {
      throw e;
    }

    console.log(`No Kes override found at ${kesOverridePath}, continuing`);
  }

  return KesOverride;
}

function loadKesOverride ( kesFolder , kesClass = 'kes.js' ) { let kesOverridePath = path . resolve ( kesFolder , kesClass ) ; let KesOverride ; try { KesOverride = require ( kesOverridePath ) ; } catch ( e ) { const fileExists = fs . existsSync ( kesOverridePath ) ; if ( fileExists ) { throw e ; } console . log ( ` ${ kesOverridePath } ` ) ; } return KesOverride ; }

Attempt to load a Kes override class.

Throw the error if it is something other than that the Kes override
class does not exist.

@param {string} kesFolder - The folder to look in for a Kes override class
@param {string} kesClass - The path/filename to look for as a Kes override class
@returns {Class} - A Kes override class


function determineKesClass(options, Kes) {
  let KesOverride;

  // If there is a kes class specified, use that
  const kesClass = get(options, 'kesClass');
  if (kesClass) {
    KesOverride = loadKesOverride(process.cwd(), kesClass);
  }
  else {
    let kesFolder;

    // Check if there is kes.js in the kes folder
    if (options.kesFolder) {
      kesFolder = options.kesFolder;
    }
    else {
      kesFolder = path.join(process.cwd(), '.kes');
    }
    KesOverride = loadKesOverride(kesFolder);

    // If the first Kes override didn't load, check if there is
    // a kes.js in the template folder.
    if (!KesOverride) {
      const template = get(options, 'template', '/path/to/nowhere');
      kesFolder = path.join(process.cwd(), template);
      KesOverride = loadKesOverride(kesFolder);
    }
  }

  return KesOverride || Kes;
}

function determineKesClass ( options , Kes ) { let KesOverride ; const kesClass = get ( options , 'kesClass' ) ; if ( kesClass ) { KesOverride = loadKesOverride ( process . cwd ( ) , kesClass ) ; } else { let kesFolder ; if ( options . kesFolder ) { kesFolder = options . kesFolder ; } else { kesFolder = path . join ( process . cwd ( ) , '.kes' ) ; } KesOverride = loadKesOverride ( kesFolder ) ; if ( ! KesOverride ) { const template = get ( options , 'template' , '/path/to/nowhere' ) ; kesFolder = path . join ( process . cwd ( ) , template ) ; KesOverride = loadKesOverride ( kesFolder ) ; } } return KesOverride || Kes ; }

Based on the information passed from the CLI by the commander
module this function determines whether to use the default Kes class
or use the override class provided by the user

@param {object} options The options passed by the commander library
@param {Class} Kes the default kes class
@returns {Class} Kes class


function failure(e) {
  if (e.message) {
    console.log(e.message);
  }
  else {
    console.log(e);
  }
  process.exit(1);
}

function failure ( e ) { if ( e . message ) { console . log ( e . message ) ; } else { console . log ( e ) ; } process . exit ( 1 ) ; }

In case of error logs the error and exit with error 1
@param {Error} e error object


function getSystemBucket(config) {
  let bucket = get(config, 'buckets.internal');
  if (bucket && typeof bucket === 'string') {
    return bucket;
  }

  bucket = get(config, 'system_bucket');
  if (bucket && typeof bucket === 'string') {
    return bucket;
  }
  return undefined;
}

function getSystemBucket ( config ) { let bucket = get ( config , 'buckets.internal' ) ; if ( bucket && typeof bucket === 'string' ) { return bucket ; } bucket = get ( config , 'system_bucket' ) ; if ( bucket && typeof bucket === 'string' ) { return bucket ; } return undefined ; }

Discover and returns the system bucket used for deployment

@param {Object} config - cumulus config object
@returns {string} name of the bucket


function buildNestedCfs(config, KesClass, options) {
  const limit = pLimit(1);
  if (config.nested_templates) {
    const nested = config.nested_templates;
    console.log('Nested templates are found!');
    const ps = Object.keys(nested).map((name) => limit(() => {
      console.log(`Compiling nested template for ${name}`);

      const newOptions = Object.assign({}, options);
      newOptions.cfFile = nested[name].cfFile;
      newOptions.configFile = nested[name].configFile;

      // no templates are used in nested stacks
      delete newOptions.template;
      delete newOptions.deployment;

      // use the parent stackname
      newOptions.stack = config.stack;
      newOptions.parent = config;
      const nestedConfig = new Config(newOptions);

      // get the bucket name from the parent
      if (!nestedConfig.bucket) {
        nestedConfig.bucket = utils.getSystemBucket(config);
      }

      // add nested deployment name
      nestedConfig.nested_cf_name = name;

      const kes = new KesClass(nestedConfig);
      return kes.uploadCF().then((uri) => {
        config.nested_templates[name].url = uri;
      });
    }));
    return Promise.all(ps)
      .then(() => config)
      .catch(utils.failure);
  }
  return Promise.resolve(config);
}

function
buildNestedCfs
(
config
,
KesClass
,
options
)
{
const
limit
=
pLimit
(
1
)
;
if
(
config
.
nested_templates
)
{
const
nested
=
config
.
nested_templates
;
console
.
log
(
'Nested templates are found!'
)
;
const
ps
=
Object
.
keys
(
nested
)
.
map
(
(
name
)
=>
limit
(
(
)
=>
{
console
.
log
(
`
${
name
}
`
)
;
const
newOptions
=
Object
.
assign
(
{
}
,
options
)
;
newOptions
.
cfFile
=
nested
[
name
]
.
cfFile
;
newOptions
.
configFile
=
nested
[
name
]
.
configFile
;
delete
newOptions
.
template
;
delete
newOptions
.
deployment
;
newOptions
.
stack
=
config
.
stack
;
newOptions
.
parent
=
config
;
const
nestedConfig
=
new
Config
(
newOptions
)
;
if
(
!
nestedConfig
.
bucket
)
{
nestedConfig
.
bucket
=
utils
.
getSystemBucket
(
config
)
;
}
nestedConfig
.
nested_cf_name
=
name
;
const
kes
=
new
KesClass
(
nestedConfig
)
;
return
kes
.
uploadCF
(
)
.
then
(
(
uri
)
=>
{
config
.
nested_templates
[
name
]
.
url
=
uri
;
}
)
;
}
)
)
;
return
Promise
.
all
(
ps
)
.
then
(
(
)
=>
config
)
.
catch
(
utils
.
failure
)
;
}
return
Promise
.
resolve
(
config
)
;
}

Builds templates nested in the main template
using the specified config and cf file paths

@param {object} config Kes config object
@param {object} KesClass the Kes Class
@param {object} options The options passed by the commander library
@return {Promise} returns a promise of an updated Kes config object


function buildCf(options, cmd) {
  const KesClass = utils.determineKesClass(options, Kes);
  let parentConfig;
  try {
    parentConfig = new Config(options);
  }
  catch (e) {
    return Promise.reject(e);
  }

  return buildNestedCfs(parentConfig, KesClass, options).then((config) => {
    const kes = new KesClass(config);
    switch (cmd) {
      case 'create':
        deprecate('"kes cf create" command is deprecated. Use "kes cf deploy" instead');
        return kes.createStack();
      case 'update':
        deprecate('"kes cf update" command is deprecated. Use "kes cf deploy" instead');
        return kes.updateStack();
      case 'upsert':
        deprecate('"kes cf upsert" command is deprecated. Use "kes cf deploy" instead');
        return kes.upsertStack();
      case 'deploy':
        return kes.deployStack();
      case 'validate':
        return kes.validateTemplate();
      case 'compile':
        return kes.compileCF();
      case 'delete':
        return kes.deleteStack();
      default:
        console.log('Wrong choice. Accepted arguments: [create|update|upsert|deploy|validate|compile]');
    }
  });
}

Builds, uploads and deploy a Cloudformation based on options passed
from the commander library

@param {object} options Options passed by the commander library
@param {string} cmd the argument selected in the CLI, e.g. deploy, update, etc.
@return {undefined}

Builds uploads and deploy a Cloudformation based on options passed from the commander library


function buildLambda(options, cmd) {
  if (cmd) {
    const KesClass = utils.determineKesClass(options, Kes);
    const config = new Config(options);
    const kes = new KesClass(config);
    kes.updateSingleLambda(cmd).then(r => utils.success(r)).catch(e => utils.failure(e));
  }
  else {
    utils.failure(new Error('Lambda name is missing'));
  }
}

function
buildLambda
(
options
,
cmd
)
{
if
(
cmd
)
{
const
KesClass
=
utils
.
determineKesClass
(
options
,
Kes
)
;
const
config
=
new
Config
(
options
)
;
const
kes
=
new
KesClass
(
config
)
;
kes
.
updateSingleLambda
(
cmd
)
.
then
(
r
=>
utils
.
success
(
r
)
)
.
catch
(
e
=>
utils
.
failure
(
e
)
)
;
}
else
{
utils
.
failure
(
new
Error
(
'Lambda name is missing'
)
)
;
}
}

Builds and uploads a lambda function based on the options passed by the commander
@param {object} options Options passed by the commander library
@param {string} cmd the argument selected in the CLI, e.g. lambda name
@return {undefined}


function sendResponse(event, context, responseStatus, responseData) {
  const responseBody = JSON.stringify({
    Status: responseStatus,
    Reason: 'See the details in CloudWatch Log Stream: ' + context.logStreamName,
    PhysicalResourceId: context.logStreamName,
    StackId: event.StackId,
    RequestId: event.RequestId,
    LogicalResourceId: event.LogicalResourceId,
    Data: responseData
  });

  console.log('RESPONSE BODY:\n', responseBody);

  const https = require('https');
  const url = require('url');

  const parsedUrl = url.parse(event.ResponseURL);
  const options = {
    hostname: parsedUrl.hostname,
    port: 443,
    path: parsedUrl.path,
    method: 'PUT',
    headers: {
      'content-type': '',
      'content-length': responseBody.length
    }
  };

  console.log('SENDING RESPONSE...\n');

  const request = https.request(options, function(response) {
    console.log('STATUS: ' + response.statusCode);
    console.log('HEADERS: ' + JSON.stringify(response.headers));
    // Tell AWS Lambda that the function execution is done
    context.done();
  });

  request.on('error', function(error) {
    console.log('sendResponse Error:' + error);
    // Tell AWS Lambda that the function execution is done
    context.done();
  });

  // write data to request body
  request.write(responseBody);
  request.end();
}

Send response to the pre - signed S3 URL


function optionsToString(options) {
    return Object.keys(options)
        .map(function processOption(key) {
            return key + "=" + options[key];
        })
        .join(",");
}

function optionsToString ( options ) { return Object . keys ( options ) . map ( function processOption ( key ) { return key + "=" + options [ key ] ; } ) . join ( "," ) ; }

Return options converted to a string

@param  {Object} options
@return {String}


function assign(target) {
    var sources = Array.prototype.slice.call(arguments, 1);

    function assignArgument(previous, source) {
        Object.keys(source).forEach(function assignItem(key) {
            previous[key] = source[key]; // eslint-disable-line no-param-reassign
        });

        return previous;
    }

    return sources.reduce(assignArgument, target);
}

function assign ( target ) { var sources = Array . prototype . slice . call ( arguments , 1 ) ; function assignArgument ( previous , source ) { Object . keys ( source ) . forEach ( function assignItem ( key ) { previous [ key ] = source [ key ] ; } ) ; return previous ; } return sources . reduce ( assignArgument , target ) ; }

Polyfill Object.assign

@param  {Object} target
@param  {Object} source1 ...
@return {Object}


function openPopupWithPost(url, postData, name, options) {
    var form = document.createElement("form");
    var win;

    form.setAttribute("method", "post");
    form.setAttribute("action", url);
    form.setAttribute("target", name);

    Object.keys(postData).forEach(function addFormItem(key) {
        var input = document.createElement("input");
        input.type = "hidden";
        input.name = key;
        input.value = postData[key];
        form.appendChild(input);
    });

    document.body.appendChild(form);

    win = window.open("/", name, options);
    win.document.write("Loading...");

    form.submit();
    document.body.removeChild(form);

    return win;
}

function openPopupWithPost ( url , postData , name , options ) { var form = document . createElement ( "form" ) ; var win ; form . setAttribute ( "method" , "post" ) ; form . setAttribute ( "action" , url ) ; form . setAttribute ( "target" , name ) ; Object . keys ( postData ) . forEach ( function addFormItem ( key ) { var input = document . createElement ( "input" ) ; input . type = "hidden" ; input . name = key ; input . value = postData [ key ] ; form . appendChild ( input ) ; } ) ; document . body . appendChild ( form ) ; win = window . open ( "/" , name , options ) ; win . document . write ( "Loading..." ) ; form . submit ( ) ; document . body . removeChild ( form ) ; return win ; }

Create a form element, add hidden inputs for all the post data
and post it into a newly opened popup

@param  {String} url
@param  {Object} postData
@param  {String} name
@param  {Object} options
@return {Object}

Create a form element add hidden inputs for all the post data and post it into a newly opened popup


function popupExecute(execute, url, name, options, callback) {
    var popupName = name || defaultPopupName();
    var popupOptions = optionsResolveCentered(assign({}, defaultOptions, options));
    var popupCallback = callback || function noop() {};
    var optionsString = optionsToString(popupOptions);
    var win = execute(url, popupName, optionsString);
    var isMessageSent = false;
    var interval;

    function popupCallbackOnce(err, data) {
        if (!isMessageSent) {
            isMessageSent = true;
            popupCallback(err, data);
        }
    }

    function onMessage(message) {
        var data = message ? message.data : undefined;

        if (data) {
            popupCallbackOnce(undefined, data);
            window.removeEventListener("message", onMessage);
        }
    }

    window.addEventListener("message", onMessage, false);

    if (win) {
        interval = setInterval(function closePopupCallback() {
            if (win == null || win.closed) {
                setTimeout(function delayWindowClosing() {
                    clearInterval(interval);
                    popupCallbackOnce(new Error("Popup closed"));
                }, 500);
            }
        }, 100);
    } else {
        popupCallbackOnce(new Error("Popup blocked"));
    }

    return win;
}

function
popupExecute
(
execute
,
url
,
name
,
options
,
callback
)
{
var
popupName
=
name
||
defaultPopupName
(
)
;
var
popupOptions
=
optionsResolveCentered
(
assign
(
{
}
,
defaultOptions
,
options
)
)
;
var
popupCallback
=
callback
||
function
noop
(
)
{
}
;
var
optionsString
=
optionsToString
(
popupOptions
)
;
var
win
=
execute
(
url
,
popupName
,
optionsString
)
;
var
isMessageSent
=
false
;
var
interval
;
function
popupCallbackOnce
(
err
,
data
)
{
if
(
!
isMessageSent
)
{
isMessageSent
=
true
;
popupCallback
(
err
,
data
)
;
}
}
function
onMessage
(
message
)
{
var
data
=
message
message
.
data
:
undefined
;
if
(
data
)
{
popupCallbackOnce
(
undefined
,
data
)
;
window
.
removeEventListener
(
"message"
,
onMessage
)
;
}
}
window
.
addEventListener
(
"message"
,
onMessage
,
false
)
;
if
(
win
)
{
interval
=
setInterval
(
function
closePopupCallback
(
)
{
if
(
win
==
||
win
.
closed
)
{
setTimeout
(
function
delayWindowClosing
(
)
{
clearInterval
(
interval
)
;
popupCallbackOnce
(
new
Error
(
"Popup closed"
)
)
;
}
,
500
)
;
}
}
,
100
)
;
}
else
{
popupCallbackOnce
(
new
Error
(
"Popup blocked"
)
)
;
}
return
win
;
}

Open a popup using the first argument. Wait for it to close.
Returns the window object

@param  {Function}
@param  {String}
@param  {String}
@param  {Object}
@param  {Function}
@return {Object}

Open a popup using the first argument . Wait for it to close . Returns the window object


function popup(url, name, options, callback) {
    return popupExecute(window.open, url, name, options, callback);
}

function popup ( url , name , options , callback ) { return popupExecute ( window . open , url , name , options , callback ) ; }

Open a popup using the first argument.
Wait for it to close and call the callback.
Set the options string using the options object
Returns the window object

@param  {String} url
@param  {String} name
@param  {Object} options
@param  {Function} callback
@return {Object}

Open a popup using the first argument . Wait for it to close and call the callback . Set the options string using the options object Returns the window object


function popupWithPost(url, postData, name, options, callback) {
    function openWithPostData(popupUrl, popupName, optionsString) {
        return openPopupWithPost(popupUrl, postData, popupName, optionsString);
    }

    return popupExecute(openWithPostData, url, name, options, callback);
}

function popupWithPost ( url , postData , name , options , callback ) { function openWithPostData ( popupUrl , popupName , optionsString ) { return openPopupWithPost ( popupUrl , postData , popupName , optionsString ) ; } return popupExecute ( openWithPostData , url , name , options , callback ) ; }

Open a popup using the first argument.
Post the data into the open popup.
Wait for it to close and call the callback.
Set the options string using the options object
Returns the window object

@param  {String} url
@param  {Object} postData
@param  {String} name
@param  {Object} options
@param  {Function} callback
@return {Object}

Open a popup using the first argument . Post the data into the open popup . Wait for it to close and call the callback . Set the options string using the options object Returns the window object


function getWrappingContentRange(editor) {
	if (editor.somethingSelected()) {
		const sel = editor.listSelections().filter(sel => sel.anchor !== sel.head)[0];
		if (sel) {
			return  comparePos(sel.anchor, sel.head) < 0
				? { from: sel.anchor, to: sel.head }
				: { from: sel.head, to: sel.anchor };
		}
	}

	// Nothing selected, find parent HTML node and return range for its content
	return getTagRangeForPos(editor, editor.getCursor());
}

function getWrappingContentRange ( editor ) { if ( editor . somethingSelected ( ) ) { const sel = editor . listSelections ( ) . filter ( sel => sel . anchor !== sel . head ) [ 0 ] ; if ( sel ) { return comparePos ( sel . anchor , sel . head ) < 0 ? { from : sel . anchor , to : sel . head } : { from : sel . head , to : sel . anchor } ; } } return getTagRangeForPos ( editor , editor . getCursor ( ) ) ; }

Returns content range that should be wrapped
@param {CodeMirror} editor


function betweenTags(editor, range) {
	if (equalCursorPos(range.anchor, range.head)) {
		const cursor = range.anchor;
		const mode = editor.getModeAt(cursor);

		if (mode.name === 'xml') {
			const left = editor.getTokenAt(cursor);
			const right = editor.getTokenAt(Object.assign({}, cursor, { ch: cursor.ch + 1 }));

			return left.type === 'tag bracket' && left.string === '>'
				&& right.type === 'tag bracket' && right.string === '</';
		}
	}
}

function
betweenTags
(
editor
,
range
)
{
if
(
equalCursorPos
(
range
.
anchor
,
range
.
head
)
)
{
const
cursor
=
range
.
anchor
;
const
mode
=
editor
.
getModeAt
(
cursor
)
;
if
(
mode
.
name
===
'xml'
)
{
const
left
=
editor
.
getTokenAt
(
cursor
)
;
const
right
=
editor
.
getTokenAt
(
Object
.
assign
(
{
}
,
cursor
,
{
ch
:
cursor
.
ch
+
1
}
)
)
;
return
left
.
type
===
'tag bracket'
&&
left
.
string
===
'>'
&&
right
.
type
===
'tag bracket'
&&
right
.
string
===
'</'
;
}
}
}

Check if given range is a single caret between tags
@param {CodeMirror} editor
@param {CodeMirror.range} range


function canExtract(editor, pos, config) {
	const tokenType = editor.getTokenTypeAt(pos);

	if (config.type === 'stylesheet') {
		return tokenType !== 'comment' && tokenType !== 'string';
	}

	if (config.syntax === 'html') {
		return tokenType === null;
	}

	if (config.syntax === 'slim' || config.syntax === 'pug') {
		return tokenType === null || tokenType === 'tag'
			|| (tokenType && /attribute/.test(tokenType));
	}

	if (config.syntax === 'haml') {
		return tokenType === null || tokenType === 'attribute';
	}

	if (config.syntax === 'jsx') {
		// JSX a bit tricky, delegate it to caller
		return true;
	}

	return false;
}

function canExtract ( editor , pos , config ) { const tokenType = editor . getTokenTypeAt ( pos ) ; if ( config . type === 'stylesheet' ) { return tokenType !== 'comment' && tokenType !== 'string' ; } if ( config . syntax === 'html' ) { return tokenType === null ; } if ( config . syntax === 'slim' || config . syntax === 'pug' ) { return tokenType === null || tokenType === 'tag' || ( tokenType && / attribute / . test ( tokenType ) ) ; } if ( config . syntax === 'haml' ) { return tokenType === null || tokenType === 'attribute' ; } if ( config . syntax === 'jsx' ) { return true ; } return false ; }

Check if abbreviation can be extracted from given position
@param {CodeMirror.Editor} editor
@param {CodeMirror.Position} pos
@param {Object} config
@return {Boolean}


function getStylesheetCompletions(editor, pos, config) {
	const line = editor.getLine(pos.line).slice(0, pos.ch);
	const prefix = extractPrefix(line, /[\w-@$]/);

	if (prefix) {
		// Make sure that current position precedes element name (e.g. not attribute,
		// class, id etc.)
		const prefixRange = {
			from: { line: pos.line, ch: pos.ch - prefix.length },
			to: pos
		};

		if (config.options && config.options.property) {
			const lowerProp = config.options.property.toLowerCase();
			// Find matching CSS property snippet for keyword completions
			const completion = getSnippetCompletions(editor, pos, config)
				.find(item => item.property && item.property === lowerProp);

			if (completion && completion.keywords.length) {
				return completion.keywords.map(kw => {
					return kw.key.indexOf(prefix) === 0 && new EmmetCompletion('value', editor, prefixRange, kw.key, kw.preview, kw.snippet);
				}).filter(Boolean);
			}
		} else {
			return getSnippetCompletions(editor, pos, config)
				.filter(completion => completion.key !== prefix && completion.key.indexOf(prefix) === 0)
				.map(completion => new EmmetCompletion('snippet', editor, prefixRange, completion.key, completion.preview, completion.snippet));
		}
	}

	return [];
}

function getStylesheetCompletions ( editor , pos , config ) { const line = editor . getLine ( pos . line ) . slice ( 0 , pos . ch ) ; const prefix = extractPrefix ( line , / [\w-@$] / ) ; if ( prefix ) { const prefixRange = { from : { line : pos . line , ch : pos . ch - prefix . length } , to : pos } ; if ( config . options && config . options . property ) { const lowerProp = config . options . property . toLowerCase ( ) ; const completion = getSnippetCompletions ( editor , pos , config ) . find ( item => item . property && item . property === lowerProp ) ; if ( completion && completion . keywords . length ) { return completion . keywords . map ( kw => { return kw . key . indexOf ( prefix ) === 0 && new EmmetCompletion ( 'value' , editor , prefixRange , kw . key , kw . preview , kw . snippet ) ; } ) . filter ( Boolean ) ; } } else { return getSnippetCompletions ( editor , pos , config ) . filter ( completion => completion . key !== prefix && completion . key . indexOf ( prefix ) === 0 ) . map ( completion => new EmmetCompletion ( 'snippet' , editor , prefixRange , completion . key , completion . preview , completion . snippet ) ) ; } } return [ ] ; }

Returns completions for stylesheet syntaxes
@param  {CodeMirror} editor
@param  {CodeMirror.Position} pos Cursor position in editor
@param  {Object} config Resolved Emmet config
@return {EmmetCompletion[]}


function getSnippetCompletions(editor, pos, config) {
	const { type, syntax } = config;

	if (!editor.state.emmetCompletions) {
		editor.state.emmetCompletions = {};
	}

	const cache = editor.state.emmetCompletions;

	if (!(syntax in cache)) {
		const registry = createSnippetsRegistry(type, syntax, config.snippets);

		cache[syntax] = type === 'stylesheet'
			? getStylesheetSnippets(registry, config)
			: getMarkupSnippets(registry, config);
	}

	return cache[syntax];
}

function getSnippetCompletions ( editor , pos , config ) { const { type , syntax } = config ; if ( ! editor . state . emmetCompletions ) { editor . state . emmetCompletions = { } ; } const cache = editor . state . emmetCompletions ; if ( ! ( syntax in cache ) ) { const registry = createSnippetsRegistry ( type , syntax , config . snippets ) ; cache [ syntax ] = type === 'stylesheet' ? getStylesheetSnippets ( registry , config ) : getMarkupSnippets ( registry , config ) ; } return cache [ syntax ] ; }

Returns all possible snippets completions for given editor context.
Completions are cached in editor for for re-use
@param  {CodeMirror.Editor} editor
@param  {CodeMirror.Position} pos
@param  {Object} config
@return {Array}

Returns all possible snippets completions for given editor context . Completions are cached in editor for for re - use


function getStylesheetSnippets(registry) {
	return convertToCSSSnippets(registry).map(snippet => {
		let preview = snippet.property;
		const keywords = snippet.keywords();
		if (keywords.length) {
			preview += `: ${removeFields(keywords.join(' | '))}`;
		} else if (snippet.value) {
			preview += `: ${removeFields(snippet.value)}`;
		}

		return {
			key: snippet.key,
			value: snippet.value,
			snippet: snippet.key,
			property: snippet.property,
			keywords: keywords.map(kw => {
				const m = kw.match(/^[\w-]+/);
				return m && {
					key: m[0],
					preview: removeFields(kw),
					snippet: kw
				};
			}).filter(Boolean),
			preview
		};
	});
}

function
getStylesheetSnippets
(
registry
)
{
return
convertToCSSSnippets
(
registry
)
.
map
(
snippet
=>
{
let
preview
=
snippet
.
property
;
const
keywords
=
snippet
.
keywords
(
)
;
if
(
keywords
.
length
)
{
preview
+=
`
${
removeFields
(
keywords
.
join
(
' | '
)
)
}
`
;
}
else
if
(
snippet
.
value
)
{
preview
+=
`
${
removeFields
(
snippet
.
value
)
}
`
;
}
return
{
key
:
snippet
.
key
,
value
:
snippet
.
value
,
snippet
:
snippet
.
key
,
property
:
snippet
.
property
,
keywords
:
keywords
.
map
(
kw
=>
{
const
m
=
kw
.
match
(
/
^[\w-]+
/
)
;
return
m
&&
{
key
:
m
[
0
]
,
preview
:
removeFields
(
kw
)
,
snippet
:
kw
}
;
}
)
.
filter
(
Boolean
)
,
preview
}
;
}
)
;
}

Returns stylesheet snippets list
@param {SnippetsRegistry} registry
@return {Array}


function getMarkupSnippets(registry, config) {
	return registry.all({ type: 'string' }).map(snippet => ({
		key: snippet.key,
		value: snippet.value,
		preview: removeFields(expand(snippet.value, config)),
		snippet: snippet.key
	}));
}

function getMarkupSnippets ( registry , config ) { return registry . all ( { type : 'string' } ) . map ( snippet => ( { key : snippet . key , value : snippet . value , preview : removeFields ( expand ( snippet . value , config ) ) , snippet : snippet . key } ) ) ; }

Returns markup snippets list
@param {SnippetsRegistry} registry
@param {Object} config
@return {Array}


function extractPrefix(str, match) {
	let offset = str.length;

	while (offset > 0) {
		if (!match.test(str[offset - 1])) {
			break;
		}
		offset--;
	}

	return str.slice(offset);
}

function extractPrefix ( str , match ) { let offset = str . length ; while ( offset > 0 ) { if ( ! match . test ( str [ offset - 1 ] ) ) { break ; } offset -- ; } return str . slice ( offset ) ; }

Extracts prefix from the end of given string that matches `match` regexp
@param {String} str
@param {RegExp} match
@return {String} Extracted prefix

Extracts prefix from the end of given string that matches match regexp


function isValidMarker(editor, marker) {
	const range = marker.find();

	// No newlines inside abbreviation
	if (range.from.line !== range.to.line) {
		return false;
	}

	// Make sure marker contains valid abbreviation
	let text = editor.getRange(range.from, range.to);
	if (!text || /^\s|\s$/g.test(text)) {
		return false;
	}

	if (marker.model && marker.model.config.syntax === 'jsx' && text[0] === '<') {
		text = text.slice(1);
	}

	if (!marker.model || marker.model.abbreviation !== text) {
		// marker contents was updated, re-parse abbreviation
		try {
			marker.model = new Abbreviation(text, range, marker.model.config);
			if (!marker.model.valid(editor, true)) {
				marker.model = null;
			}
		} catch (err) {
			console.warn(err);
			marker.model = null;
		}
	}

	return Boolean(marker.model && marker.model.snippet);
}

function isValidMarker ( editor , marker ) { const range = marker . find ( ) ; if ( range . from . line !== range . to . line ) { return false ; } let text = editor . getRange ( range . from , range . to ) ; if ( ! text || / ^\s|\s$ / g . test ( text ) ) { return false ; } if ( marker . model && marker . model . config . syntax === 'jsx' && text [ 0 ] === '<' ) { text = text . slice ( 1 ) ; } if ( ! marker . model || marker . model . abbreviation !== text ) { try { marker . model = new Abbreviation ( text , range , marker . model . config ) ; if ( ! marker . model . valid ( editor , true ) ) { marker . model = null ; } } catch ( err ) { console . warn ( err ) ; marker . model = null ; } } return Boolean ( marker . model && marker . model . snippet ) ; }

Ensures that given editor Emmet abbreviation marker contains valid Emmet abbreviation
and updates abbreviation model if required
@param {CodeMirror} editor
@param {CodeMirror.TextMarket} marker
@return {Boolean} `true` if marker contains valid abbreviation


function (property) {
        var def = this._definition[property];
        if (def.type === 'boolean') {
            // if it's a bool, just flip it
            this[property] = !this[property];
        } else if (def && def.values) {
            // If it's a property with an array of values
            // skip to the next one looping back if at end.
            this[property] = arrayNext(def.values, this[property]);
        } else {
            throw new TypeError('Can only toggle properties that are type `boolean` or have `values` array.');
        }
        return this;
    }

Toggle boolean properties or properties that have a `values` array in its definition.

Toggle boolean properties or properties that have a values array in its definition .


function (attr) {
        if (attr == null) return !!Object.keys(this._changed).length;
        if (has(this._derived, attr)) {
            return this._derived[attr].depList.some(function (dep) {
                return this.hasChanged(dep);
            }, this);
        }
        return has(this._changed, attr);
    }

function ( attr ) { if ( attr == null ) return ! ! Object . keys ( this . _changed ) . length ; if ( has ( this . _derived , attr ) ) { return this . _derived [ attr ] . depList . some ( function ( dep ) { return this . hasChanged ( dep ) ; } , this ) ; } return has ( this . _changed , attr ) ; }

Determine if the model has changed since the last `"change"` event. If you specify an attribute name, determine if that attribute has changed.

Determine if the model has changed since the last change event . If you specify an attribute name determine if that attribute has changed .


function (propertyName) {
        if (!this._eventBubblingHandlerCache[propertyName]) {
            this._eventBubblingHandlerCache[propertyName] = function (name, model, newValue) {
                if (changeRE.test(name)) {
                    this.trigger('change:' + propertyName + '.' + name.split(':')[1], model, newValue);
                } else if (name === 'change') {
                    this.trigger('change', this);
                }
            }.bind(this);
        }
        return this._eventBubblingHandlerCache[propertyName];
    }

function ( propertyName ) { if ( ! this . _eventBubblingHandlerCache [ propertyName ] ) { this . _eventBubblingHandlerCache [ propertyName ] = function ( name , model , newValue ) { if ( changeRE . test ( name ) ) { this . trigger ( 'change:' + propertyName + '.' + name . split ( ':' ) [ 1 ] , model , newValue ) ; } else if ( name === 'change' ) { this . trigger ( 'change' , this ) ; } } . bind ( this ) ; } return this . _eventBubblingHandlerCache [ propertyName ] ; }

Returns a bound handler for doing event bubbling while adding a name to the change string.

Returns a bound handler for doing event bubbling while adding a name to the change string .


function createDerivedProperty(modelProto, name, definition) {
    var def = modelProto._derived[name] = {
        fn: isFunction(definition) ? definition : definition.fn,
        cache: (definition.cache !== false),
        depList: definition.deps || []
    };

    // add to our shared dependency list
    def.depList.forEach(function (dep) {
        modelProto._deps[dep] = union(modelProto._deps[dep] || [], [name]);
    });

    // defined a top-level getter for derived names
    Object.defineProperty(modelProto, name, {
        get: function () {
            return this._getDerivedProperty(name);
        },
        set: function () {
            throw new TypeError("`" + name + "` is a derived property, it can't be set directly.");
        }
    });
}

helper for creating derived property definitions


function Image(image, address){

	var at = this.attributes = image.attribs;

	this.name = path.basename(at.src, path.extname(at.src));
	this.saveTo = path.dirname(require.main.filename) + "/";
	this.extension = path.extname(at.src);
	this.address = url.resolve(address, at.src);
	this.fromAddress = address;
}

function Image ( image , address ) { var at = this . attributes = image . attribs ; this . name = path . basename ( at . src , path . extname ( at . src ) ) ; this . saveTo = path . dirname ( require . main . filename ) + "/" ; this . extension = path . extname ( at . src ) ; this . address = url . resolve ( address , at . src ) ; this . fromAddress = address ; }


function shipitTask(grunt) {
  'use strict';

  // Init shipit
  grunt.shipit = new Shipit();

  grunt.registerTask('shipit', 'Shipit Task', function (env) {
    var config = grunt.config.get('shipit');

    grunt.shipit.environment = env;

    // Support legacy options.
    if (!config.default && config.options)
      config.default = config.options;

    grunt.shipit
      .initConfig(config)
      .initialize();
  });
}

function
shipitTask
(
grunt
)
{
'use strict'
;
grunt
.
shipit
=
new
Shipit
(
)
;
grunt
.
registerTask
(
'shipit'
,
'Shipit Task'
,
function
(
env
)
{
var
config
=
grunt
.
config
.
get
(
'shipit'
)
;
grunt
.
shipit
.
environment
=
env
;
if
(
!
config
.
default
&&
config
.
options
)
config
.
default
=
config
.
options
;
grunt
.
shipit
.
initConfig
(
config
)
.
initialize
(
)
;
}
)
;
}


function injectTemplate (s, node, offset, id) {
  const t = node.src ? readSrc(id, node.src) : node.content

  // Compile template
  const compiled = compiler.compile(t)
  const renderFuncs = '\nrender: ' + toFunction(compiled.render) + ',' +
    '\nstaticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + '],'
  s.appendLeft(offset, renderFuncs)
  return renderFuncs
}

function
injectTemplate
(
s
,
node
,
offset
,
id
)
{
const
t
=
node
.
src
readSrc
(
id
,
node
.
src
)
:
node
.
content
const
compiled
=
compiler
.
compile
(
t
)
const
renderFuncs
=
'\nrender: '
+
\n
+
toFunction
(
compiled
.
render
)
+
','
+
'\nstaticRenderFns: ['
+
\n
compiled
.
staticRenderFns
.
map
(
toFunction
)
.
join
(
','
)
'],'
}

Only support for es5 modules

@param script
@param template
@returns {string}


function _defaultCheckSize(size) {
  return function (raw) {
    if (raw.length < size) {
      return false;
    }
    this.buffer = raw.substr(size);
    return raw.substr(0, size);
  };
}

function _defaultCheckSize ( size ) { return function ( raw ) { if ( raw . length < size ) { return false ; } this . buffer = raw . substr ( size ) ; return raw . substr ( 0 , size ) ; } ; }

A closure factory to build the checkSize function for most of our handlers


function (configFile, options) {
    DataStream.call(this);
    this.options = options || {};
    var self = this;

    // apply config
    this.configFile = configFile;

    this.init();

    // Bundles streams
    this.bundles = {};

    // Let return instance before build
    this.buildConfig = this.compileConfig(configFile, self.options);

    this.makeEmptyStreamsUnreadable(this.buildConfig);

    var isFatalErrors = !this.isAllModulesExists(this.buildConfig);
    if (isFatalErrors) {
        this.readable = false;
        this.style.readable = false;
        this.sourceMap.readable = false;
    } else {
        this._initBundlesStreams(this.buildConfig.bundles);
    }
    process.nextTick(function () {
        if (!isFatalErrors) {
            if (configFile) {
                var buildResult = self.build(self.buildConfig);

                self.write(buildResult.source);
                self.style.write(buildResult.style);
                self.sourceMap.write(buildResult.sourceMap.toString());
                self._streamBundles(buildResult.bundles);
            } else {
                self.log.write('lmd usage:\n\t    ' + 'lmd'.blue + ' ' + 'config.lmd.js(on)'.green + ' [output.lmd.js]\n');
            }
        } else {
            self.printFatalErrors(self.buildConfig);
        }
        self.closeStreams();
    });
}

function
(
configFile
,
options
)
{
DataStream
.
call
(
this
)
;
this
.
options
=
options
||
{
}
;
var
self
=
this
;
this
.
configFile
=
configFile
;
this
.
init
(
)
;
this
.
bundles
=
{
}
;
this
.
buildConfig
=
this
.
compileConfig
(
configFile
,
self
.
options
)
;
this
.
makeEmptyStreamsUnreadable
(
this
.
buildConfig
)
;
var
isFatalErrors
=
!
this
.
isAllModulesExists
(
this
.
buildConfig
)
;
if
(
isFatalErrors
)
{
this
.
readable
=
false
;
this
.
style
.
readable
=
false
;
this
.
sourceMap
.
readable
=
false
;
}
else
{
this
.
_initBundlesStreams
(
this
.
buildConfig
.
bundles
)
;
}
process
.
nextTick
(
function
(
)
{
if
(
!
isFatalErrors
)
{
if
(
configFile
)
{
var
buildResult
=
self
.
build
(
self
.
buildConfig
)
;
self
.
write
(
buildResult
.
source
)
;
self
.
style
.
write
(
buildResult
.
style
)
;
self
.
sourceMap
.
write
(
buildResult
.
sourceMap
.
toString
(
)
)
;
self
.
_streamBundles
(
buildResult
.
bundles
)
;
}
else
{
self
.
log
.
write
(
'lmd usage:\n\t    '
+
\n
+
\t
+
'lmd'
.
blue
+
' '
)
;
}
}
else
'config.lmd.js(on)'
.
green
' [output.lmd.js]\n'
}
)
;
}

LmdBuilder LMD Package Builder

LmdBuilder is readable stream

@constructor

@inherits Stream

@param {String} configFile
@param {Object} [options]

@example

new LmdBuilder("config.json", {
warn: true
})
.pipe(process.stdout);


function getSandboxMap(ast) {
        var map = {};

        walker.with_walkers({
            // looking for first var with sandbox item;
            "var" : function (vars) {
                for (var i = 0, c = vars.length, varItem; i < c; i++) {
                    varItem = vars[i];
                    if (varItem[0] === 'sandbox') {
                        varItem[1][1].forEach(function (objectVar) {
                            map[objectVar[0]] = objectVar[1][1];
                        });
                        throw 0;
                    }
                }
            }
        }, function () {
            try {
                return walker.walk(ast);
            } catch (e) {}
        });

        return map;
    }

function getSandboxMap ( ast ) { var map = { } ; walker . with_walkers ( { "var" : function ( vars ) { for ( var i = 0 , c = vars . length , varItem ; i < c ; i ++ ) { varItem = vars [ i ] ; if ( varItem [ 0 ] === 'sandbox' ) { varItem [ 1 ] [ 1 ] . forEach ( function ( objectVar ) { map [ objectVar [ 0 ] ] = objectVar [ 1 ] [ 1 ] ; } ) ; throw 0 ; } } } } , function ( ) { try { return walker . walk ( ast ) ; } catch ( e ) { } } ) ; return map ; }

Uses variable sandbox for create replacement map

@param {Object} ast toplevel AST

@return {Object} {name: replaceName} map


function breakSandbox(ast, replaceMap) {
        var sandboxName = ast[2][0] || 'sb';

        var newAst = walker.with_walkers({
            // lookup for dot
            // looking for this pattern
            // ["dot", ["name", "sb"], "require"] -> ["name", map["require"]]
            "dot" : function () {
                if (this[1] && this[1][0] === "name" && this[1][1] === sandboxName) {
                    var sourceName = this[2];
                    return ["name", replaceMap[sourceName]];
                }
            }
        }, function () {
            return walker.walk(ast);
        });

        // remove IEFE's `sb` or whatever argument
        newAst[1][2] = [];

        return newAst;
    }

function breakSandbox ( ast , replaceMap ) { var sandboxName = ast [ 2 ] [ 0 ] || 'sb' ; var newAst = walker . with_walkers ( { "dot" : function ( ) { if ( this [ 1 ] && this [ 1 ] [ 0 ] === "name" && this [ 1 ] [ 1 ] === sandboxName ) { var sourceName = this [ 2 ] ; return [ "name" , replaceMap [ sourceName ] ] ; } } } , function ( ) { return walker . walk ( ast ) ; } ) ; newAst [ 1 ] [ 2 ] = [ ] ; return newAst ; }

Brakes sendbox in one module

@param {Object} ast
@param {Object} replaceMap

@return {Object} call AST


function () {
                if (isSandboxVariableWiped) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem[0] === 'sandbox') {
                        isSandboxVariableWiped = true;
                        this[1].splice(i, 1);

                        return this;
                    }
                }
            }

function ( ) { if ( isSandboxVariableWiped ) { return ; } for ( var i = 0 , c = this [ 1 ] . length , varItem ; i < c ; i ++ ) { varItem = this [ 1 ] [ i ] ; if ( varItem [ 0 ] === 'sandbox' ) { isSandboxVariableWiped = true ; this [ 1 ] . splice ( i , 1 ) ; return this ; } } }


function getEvents(ast) {
        var usage = {},
            eventIndex = 0;

        walker.with_walkers({
            // looking for first var with sandbox item;
            "call" : function () {
                if (this[1] && this[2][0]) {
                    var functionName = this[1][1];
                    switch (functionName) {
                        case "lmd_on":
                        case "lmd_trigger":
                            var eventName = this[2][0][1];
                            if (!usage[eventName]) {
                                usage[eventName] = {
                                    on: 0,
                                    trigger: 0,
                                    eventIndex: eventIndex
                                };
                                eventIndex++;
                            }
                            if (functionName === "lmd_on") {
                                usage[eventName].on++;
                            } else {
                                usage[eventName].trigger++;
                            }
                            break;
                    }
                }
            }
        }, function () {
            return walker.walk(ast);
        });

        return usage;
    }

function getEvents ( ast ) { var usage = { } , eventIndex = 0 ; walker . with_walkers ( { "call" : function ( ) { if ( this [ 1 ] && this [ 2 ] [ 0 ] ) { var functionName = this [ 1 ] [ 1 ] ; switch ( functionName ) { case "lmd_on" : case "lmd_trigger" : var eventName = this [ 2 ] [ 0 ] [ 1 ] ; if ( ! usage [ eventName ] ) { usage [ eventName ] = { on : 0 , trigger : 0 , eventIndex : eventIndex } ; eventIndex ++ ; } if ( functionName === "lmd_on" ) { usage [ eventName ] . on ++ ; } else { usage [ eventName ] . trigger ++ ; } break ; } } } } , function ( ) { return walker . walk ( ast ) ; } ) ; return usage ; }

Collects all plugins events with usage and event index

{
eventIndex: 3, // relative event index
on: 1,         // number of listeners
trigger: 2     // number of triggers
}

@param {Object} ast toplevel AST

@return {Object} toplevel AST


function wipeLmdEvents(ast) {
        var itemsToWipe = ['lmd_on', 'lmd_trigger', 'lmd_events'];

        return walker.with_walkers({
            // wipe lmdEvents variables
            "var": function () {
                if (!itemsToWipe.length) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem) {
                        var itemIndex = itemsToWipe.indexOf(varItem[0]);
                        if (itemIndex !== -1) {
                            itemsToWipe.splice(itemIndex, 1);
                            this[1].splice(i, 1);
                            i--;
                        }
                    }
                }
            }
        }, function () {
            return walker.walk(ast);
        });
    }

function wipeLmdEvents ( ast ) { var itemsToWipe = [ 'lmd_on' , 'lmd_trigger' , 'lmd_events' ] ; return walker . with_walkers ( { "var" : function ( ) { if ( ! itemsToWipe . length ) { return ; } for ( var i = 0 , c = this [ 1 ] . length , varItem ; i < c ; i ++ ) { varItem = this [ 1 ] [ i ] ; if ( varItem ) { var itemIndex = itemsToWipe . indexOf ( varItem [ 0 ] ) ; if ( itemIndex !== - 1 ) { itemsToWipe . splice ( itemIndex , 1 ) ; this [ 1 ] . splice ( i , 1 ) ; i -- ; } } } } } , function ( ) { return walker . walk ( ast ) ; } ) ; }

Wipes lmd_on, lmd_trigger, lmd_events variables from source

@param {Object} ast

@return {Object} modified ast


function () {
                if (!itemsToWipe.length) {
                    return;
                }

                for (var i = 0, c = this[1].length, varItem; i < c; i++) {
                    varItem = this[1][i];
                    if (varItem) {
                        var itemIndex = itemsToWipe.indexOf(varItem[0]);
                        if (itemIndex !== -1) {
                            itemsToWipe.splice(itemIndex, 1);
                            this[1].splice(i, 1);
                            i--;
                        }
                    }
                }
            }

function ( ) { if ( ! itemsToWipe . length ) { return ; } for ( var i = 0 , c = this [ 1 ] . length , varItem ; i < c ; i ++ ) { varItem = this [ 1 ] [ i ] ; if ( varItem ) { var itemIndex = itemsToWipe . indexOf ( varItem [ 0 ] ) ; if ( itemIndex !== - 1 ) { itemsToWipe . splice ( itemIndex , 1 ) ; this [ 1 ] . splice ( i , 1 ) ; i -- ; } } } }


function (optionName, isApply, isInline) {
        // /*if ($P.CSS || $P.JS || $P.ASYNC) {*/
        var inlinePreprocessorBlock = isInline ? '/*if (' + optionName + ') {*/' : 'if (' + optionName + ') {',
            bracesCounter = 0,

            startIndex = lmd_js.indexOf(inlinePreprocessorBlock),
            startLength = inlinePreprocessorBlock.length,

            endIndex = startIndex + inlinePreprocessorBlock.length,
            endLength = isInline ? 5 : 1;

        if (startIndex === -1) {
            return false;
        }

        // lookup for own }
        while (lmd_js.length > endIndex) {
            if (lmd_js[endIndex] === '{') {
                bracesCounter++;
            }
            if (lmd_js[endIndex] === '}') {
                bracesCounter--;
            }

            // found!
            if (bracesCounter === -1) {
                if (isInline) {
                    // step back
                    endIndex -= 2;
                } else {
                    // remove leading spaces from open part
                    while (startIndex) {
                        startIndex--;
                        startLength++;
                        if (lmd_js[startIndex] !== '\t' && lmd_js[startIndex] !== ' ') {
                            startIndex++;
                            startLength--;
                            break;
                        }
                    }

                    // remove leading spaces from close part
                    while (endIndex) {
                        endIndex--;
                        endLength++;
                        if (lmd_js[endIndex] !== '\t' && lmd_js[endIndex] !== ' ') {
                            endIndex++;
                            endLength--;
                            break;
                        }
                    }
                    // add front \n
                    endLength++;
                    startLength++;
                }

                if (isApply) {
                    // wipe preprocessor blocks only
                    // open
                    lmd_js = lmd_js.substr(0, startIndex) + lmd_js.substr(startIndex + startLength);

                    // close
                    lmd_js = lmd_js.substr(0, endIndex - startLength) + lmd_js.substr(endIndex + endLength - startLength);

                    if (!isInline) {
                        // indent block back
                        var blockForIndent = lmd_js.substr(startIndex, endIndex - startLength - startIndex);

                        blockForIndent = blockForIndent
                            .split('\n')
                            .map(function (line) {
                                return line.replace(/^\s{4}/, '');
                            })
                            .join('\n');

                        lmd_js = lmd_js.substr(0, startIndex) + blockForIndent + lmd_js.substr(endIndex - startLength);
                    }
                } else {
                    // wipe all
                    lmd_js = lmd_js.substr(0, startIndex) + lmd_js.substr(endIndex + endLength);
                }
                break;
            }
            endIndex++;
        }

        return true;
    }

function
(
optionName
,
isApply
,
isInline
)
{
var
inlinePreprocessorBlock
=
isInline
'/*if ('
+
optionName
+
') {*/'
:
'if ('
+
optionName
+
') {'
,
bracesCounter
=
0
,
startIndex
=
lmd_js
.
indexOf
(
inlinePreprocessorBlock
)
,
startLength
=
inlinePreprocessorBlock
.
length
,
endIndex
=
startIndex
+
inlinePreprocessorBlock
.
length
,
endLength
=
isInline
5
:
1
;
if
(
startIndex
===
1
)
{
return
false
;
}
while
(
lmd_js
.
length
>
endIndex
)
{
if
(
lmd_js
[
endIndex
]
===
'{'
)
{
bracesCounter
++
;
}
if
(
lmd_js
[
endIndex
]
===
'}'
)
{
bracesCounter
;
}
if
(
bracesCounter
===
1
)
{
if
(
isInline
)
{
endIndex
-=
2
;
}
else
{
while
(
startIndex
)
{
startIndex
;
startLength
++
;
if
(
lmd_js
[
startIndex
]
!==
'\t'
&&
\t
)
lmd_js
[
startIndex
]
!==
' '
}
{
startIndex
++
;
startLength
;
break
;
}
while
(
endIndex
)
{
endIndex
;
endLength
++
;
if
(
lmd_js
[
endIndex
]
!==
'\t'
&&
\t
)
lmd_js
[
endIndex
]
!==
' '
}
{
endIndex
++
;
endLength
;
break
;
}
}
endLength
++
;
startLength
++
;
}
if
(
isApply
)
{
lmd_js
=
lmd_js
.
substr
(
0
,
startIndex
)
+
lmd_js
.
substr
(
startIndex
+
startLength
)
;
lmd_js
=
lmd_js
.
substr
(
0
,
endIndex
startLength
)
+
lmd_js
.
substr
(
endIndex
+
endLength
startLength
)
;
if
(
!
isInline
)
{
var
blockForIndent
=
lmd_js
.
substr
(
startIndex
,
endIndex
startLength
startIndex
)
;
blockForIndent
=
blockForIndent
.
split
(
'\n'
)
.
\n
map
.
(
function
(
line
)
{
return
line
.
replace
(
/
^\s{4}
/
,
''
)
;
}
)
join
;
(
'\n'
)
}
}
else
\n
}
lmd_js
=
lmd_js
.
substr
(
0
,
startIndex
)
+
blockForIndent
+
lmd_js
.
substr
(
endIndex
startLength
)
;
}

Applies or removes block from lmd_js

@param {String} optionName block name eg $P.CACHE
@param isApply  apply or remove block
@param isInline block is inline (based on block comment)

@returns {Boolean} true if block was found, false - not found


function (e) {
                if (isNotLoaded) {
                    isNotLoaded = 0;
                    // register or cleanup
                    link.removeAttribute('id');

                    if (!e) {
                        sb.trigger('*:request-error', moduleName, module);
                    }
                    callback(e ? sb.register(moduleName, link) : head.removeChild(link) && sb.undefined); // e === undefined if error
                }
            }

function ( e ) { if ( isNotLoaded ) { isNotLoaded = 0 ; link . removeAttribute ( 'id' ) ; if ( ! e ) { sb . trigger ( '*:request-error' , moduleName , module ) ; } callback ( e ? sb . register ( moduleName , link ) : head . removeChild ( link ) && sb . undefined ) ; } }


function d3_layout_hierarchyRebind(object, hierarchy) {
  object.sort = d3.rebind(object, hierarchy.sort);
  object.children = d3.rebind(object, hierarchy.children);
  object.links = d3_layout_hierarchyLinks;
  object.value = d3.rebind(object, hierarchy.value);

  // If the new API is used, enabling inlining.
  object.nodes = function(d) {
    d3_layout_hierarchyInline = true;
    return (object.nodes = object)(d);
  };

  return object;
}

function d3_layout_hierarchyRebind ( object , hierarchy ) { object . sort = d3 . rebind ( object , hierarchy . sort ) ; object . children = d3 . rebind ( object , hierarchy . children ) ; object . links = d3_layout_hierarchyLinks ; object . value = d3 . rebind ( object , hierarchy . value ) ; object . nodes = function ( d ) { d3_layout_hierarchyInline = true ; return ( object . nodes = object ) ( d ) ; } ; return object ; }

A method assignment helper for hierarchy subclasses.

A method assignment helper for hierarchy subclasses .


function position(row, u, rect, flush) {
    var i = -1,
        n = row.length,
        x = rect.x,
        y = rect.y,
        v = u ? round(row.area / u) : 0,
        o;
    if (u == rect.dx) { // horizontal subdivision
      if (flush || v > rect.dy) v = v ? rect.dy : 0; // over+underflow
      while (++i < n) {
        o = row[i];
        o.x = x;
        o.y = y;
        o.dy = v;
        x += o.dx = v ? round(o.area / v) : 0;
      }
      o.z = true;
      o.dx += rect.x + rect.dx - x; // rounding error
      rect.y += v;
      rect.dy -= v;
    } else { // vertical subdivision
      if (flush || v > rect.dx) v = v ? rect.dx : 0; // over+underflow
      while (++i < n) {
        o = row[i];
        o.x = x;
        o.y = y;
        o.dx = v;
        y += o.dy = v ? round(o.area / v) : 0;
      }
      o.z = false;
      o.dy += rect.y + rect.dy - y; // rounding error
      rect.x += v;
      rect.dx -= v;
    }
  }

function position ( row , u , rect , flush ) { var i = - 1 , n = row . length , x = rect . x , y = rect . y , v = u ? round ( row . area / u ) : 0 , o ; if ( u == rect . dx ) { if ( flush || v > rect . dy ) v = v ? rect . dy : 0 ; while ( ++ i < n ) { o = row [ i ] ; o . x = x ; o . y = y ; o . dy = v ; x += o . dx = v ? round ( o . area / v ) : 0 ; } o . z = true ; o . dx += rect . x + rect . dx - x ; rect . y += v ; rect . dy -= v ; } else { if ( flush || v > rect . dx ) v = v ? rect . dx : 0 ; while ( ++ i < n ) { o = row [ i ] ; o . x = x ; o . y = y ; o . dx = v ; y += o . dy = v ? round ( o . area / v ) : 0 ; } o . z = false ; o . dy += rect . y + rect . dy - y ; rect . x += v ; rect . dx -= v ; } }

Positions the specified row of nodes. Modifies `rect`.

Positions the specified row of nodes . Modifies rect .


function(classes) {
            var map = {};

            function find(name, data) {
                var node = map[name], i;
                if (!node) {
                    node = map[name] = data || {name: name, children: []};
                    if (name.length) {
                        node.parent = find("");
                        node.parent.children.push(node);
                        node.name = name;
                        node.key = escapeId(name);
                    }
                }
                return node;
            }

            classes.forEach(function(d) {
                find(d.name, d);
            });

            return map[""];
        }

function ( classes ) { var map = { } ; function find ( name , data ) { var node = map [ name ] , i ; if ( ! node ) { node = map [ name ] = data || { name : name , children : [ ] } ; if ( name . length ) { node . parent = find ( "" ) ; node . parent . children . push ( node ) ; node . name = name ; node . key = escapeId ( name ) ; } } return node ; } classes . forEach ( function ( d ) { find ( d . name , d ) ; } ) ; return map [ "" ] ; }

Lazily construct the package hierarchy from class names.

Lazily construct the package hierarchy from class names .


function stringify(object) {
    var properties = [];
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            properties.push(quote(key) + ':' + getValue(object[key]));
        }
    }
    return "{" + properties.join(",") + "}";
}

function stringify ( object ) { var properties = [ ] ; for ( var key in object ) { if ( object . hasOwnProperty ( key ) ) { properties . push ( quote ( key ) + ':' + getValue ( object [ key ] ) ) ; } } return "{" + properties . join ( "," ) + "}" ; }


function countIf() {
		var self = this, ret;
		if (self[0].start && analyzing.indexOf(self) < 0) {
			var decision = self[1];
			var lineId = self[0].name + ':' + (self[0].start.line + lineOffset);

			self[1] = wrapCondition(decision, lineId);

			// We are adding new lines, make sure code blocks are actual blocks
			if (self[2] && self[2][0].start && self[2][0].start.value != "{") {
				self[2] = [ "block", [self[2]]];
			}

			if (self[3] && self[3][0].start && self[3][0].start.value != "{") {
				self[3] = [ "block", [self[3]]];
			}
		}

		ret = countLine.call(self);

		if (decision) {
			analyzing.pop(decision);
		}

		return ret;
	}

function countIf ( ) { var self = this , ret ; if ( self [ 0 ] . start && analyzing . indexOf ( self ) < 0 ) { var decision = self [ 1 ] ; var lineId = self [ 0 ] . name + ':' + ( self [ 0 ] . start . line + lineOffset ) ; self [ 1 ] = wrapCondition ( decision , lineId ) ; if ( self [ 2 ] && self [ 2 ] [ 0 ] . start && self [ 2 ] [ 0 ] . start . value != "{" ) { self [ 2 ] = [ "block" , [ self [ 2 ] ] ] ; } if ( self [ 3 ] && self [ 3 ] [ 0 ] . start && self [ 3 ] [ 0 ] . start . value != "{" ) { self [ 3 ] = [ "block" , [ self [ 3 ] ] ] ; } } ret = countLine . call ( self ) ; if ( decision ) { analyzing . pop ( decision ) ; } return ret ; }

Walker for 'if' nodes. It overrides countLine because we want to instrument conditions.

'this' is an if node, so
'this[0]' is the node descriptor
'this[1]' is the decision block
'this[2]' is the 'then' code block
'this[3]' is the 'else' code block

Note that if/else if/else in AST are represented as nested if/else

Walker for if nodes . It overrides countLine because we want to instrument conditions .


function wrapCondition(decision, lineId, parentPos) {
		if (options.condition === false) {
			// condition coverage is disabled
			return decision;
		}

		if (isSingleCondition(decision)) {
			var pos = getPositionStart(decision, parentPos);
			var condId = lineId + ":" + pos;

			analyzing.push(decision);
			allConditions.push(condId);
			return ["call",
                ["dot", ["name", "require"], "coverage_condition"],
				[
					[ "string", moduleName ],
					[ "string", condId],
					decision
				]
			];
		} else {
			decision[2] = wrapCondition(decision[2], lineId, getPositionStart(decision, parentPos));
			decision[3] = wrapCondition(decision[3], lineId, getPositionEnd(decision, parentPos));

			return decision;
		}
	}

function wrapCondition ( decision , lineId , parentPos ) { if ( options . condition === false ) { return decision ; } if ( isSingleCondition ( decision ) ) { var pos = getPositionStart ( decision , parentPos ) ; var condId = lineId + ":" + pos ; analyzing . push ( decision ) ; allConditions . push ( condId ) ; return [ "call" , [ "dot" , [ "name" , "require" ] , "coverage_condition" ] , [ [ "string" , moduleName ] , [ "string" , condId ] , decision ] ] ; } else { decision [ 2 ] = wrapCondition ( decision [ 2 ] , lineId , getPositionStart ( decision , parentPos ) ) ; decision [ 3 ] = wrapCondition ( decision [ 3 ] , lineId , getPositionEnd ( decision , parentPos ) ) ; return decision ; } }

This is the key function for condition coverage as it wraps every condition in
a function call.
The condition id is generated fron the lineId (@see countLine) plus the character
position of the condition.

This is the key function for condition coverage as it wraps every condition in a function call . The condition id is generated fron the lineId (


function isSingleCondition(decision) {
		if (decision[0].start && decision[0].name != "binary") {
			return true;
		} else if (decision[1] == "&&" || decision[1] == "||") {
			return false;
		} else {
			return true;
		}
	}

function isSingleCondition ( decision ) { if ( decision [ 0 ] . start && decision [ 0 ] . name != "binary" ) { return true ; } else if ( decision [ 1 ] == "&&" || decision [ 1 ] == "||" ) { return false ; } else { return true ; } }

Wheter or not the if decision has only one boolean condition


function countLabel() {
		var ret;
		if (this[0].start && analyzing.indexOf(this) < 0) {
			var content = this[2];

			if (content[0].name == "for" && content[4] && content[4].name != "block") {
				content[4] = [ "block", [content[4]]];
			}
			analyzing.push(content);

			var ret = countLine.call(this);

			analyzing.pop(content);
		}
		return ret;
	}

function countLabel ( ) { var ret ; if ( this [ 0 ] . start && analyzing . indexOf ( this ) < 0 ) { var content = this [ 2 ] ; if ( content [ 0 ] . name == "for" && content [ 4 ] && content [ 4 ] . name != "block" ) { content [ 4 ] = [ "block" , [ content [ 4 ] ] ] ; } analyzing . push ( content ) ; var ret = countLine . call ( this ) ; analyzing . pop ( content ) ; } return ret ; }

Label nodes need special treatment as well.

myLabel : for (;;) {
//whateveer code here
continue myLabel
}

Label can be wrapped by countLine, hovewer the subsequent for shouldn't be wrapped.

instrumentation("label");
mylabel : instrumentation("for")
for (;;) {}

The above code would be wrong.

This function makes sure that the 'for' after a label is not instrumented and that
the 'for' content is wrapped in a block.

I'm don't think it's reasonable to use labels with something that is not a 'for' block.
In that case the instrumented code might easily break.

Label nodes need special treatment as well .