<commit_before>// Export selectors engine
var $$ = Dom7;
//// load js function
function loadJS(u, c, a, i ) {
	var d = document,
		t = 'script',
		o = d.createElement(t),
		s = d.getElementsByTagName(t)[0];
	o.async = true;
	o.id = i;
	o.src = u;
	if (c) {
		o.addEventListener('load', function(e) {
			c(null, e);
		}, false);
	}
	s.parentNode.insertBefore(o, s);
}
//// load Disqus , it is async now,support spa
//function loadDisqus(commentDom) {
//	var disqus_username=$$('meta[name="disqus_username"]').attr("content");
//	commentDom.html('

');
//	if ($$("script#disqus").length == 0) {
//		loadJS("http://"+disqus_username+".disqus.com/embed.js", function() {
//			var disqus_identifier = commentDom.data("disqus_identifier");
//			var disqus_url = commentDom.data("disqus_url");
//			var disqus_title = commentDom.data("disqus_title");
//			DISQUS.reset({
//				reload: true,
//				config: function() {
//					this.page.identifier = disqus_identifier;
//					this.page.url = disqus_url;
//					this.page.title = disqus_title;
//				}
//			});
//		}, true, "disqus");
//	} else {
//		var disqus_identifier = commentDom.data("disqus_identifier");
//		var disqus_url = commentDom.data("disqus_url");
//		var disqus_title = commentDom.data("disqus_title");
//		DISQUS.reset({
//			reload: true,
//			config: function() {
//				this.page.identifier = disqus_identifier;
//				this.page.url = disqus_url;
//				this.page.title = disqus_title;
//			}
//		});
//	}
//}
//// check whether load Disqus or not, if load,check which commentDom to load to,it is perfect now
//function checkDisqus() {
//	var commentDom = $$(".page").find(".comment");
//	if (commentDom.length > 0) {
//		commentDom.find("#disqus_thread").remove();
//		if (commentDom.length == 1) {
//			if ($$(".view-main").find(".page").length == 1 || $$(".page-from-left-to-center").find(".comment").length > 0 || $$(".page-on-center").find(".comment").length > 0) {
//				loadDisqus(commentDom);
//			}
//		} else {
//			if ($$(".page-from-left-to-center").find(".comment").length > 0) {
//				commentDom = $$(".page-from-left-to-center").find(".comment");
//			}
//			if ($$(".page-on-center").find(".comment").length > 0) {
//				commentDom = $$(".page-on-center").find(".comment");
//			}
//			loadDisqus(commentDom);
//		}
//	}
//}
// load Baidu Analytics
//function loadBA(){
//	$$("script#baidu_analytics").remove();
//	var ba_track_id=$$('meta[name="ba_track_id"]').attr("content");
//	var _hmt = _hmt || [];
//	loadJS("http://hm.baidu.com/hm.js?"+ba_track_id,function(){},true,"baidu_analytics");
//}

// Initialize app
var myApp = new Framework7({
	material: true,
	pushState: true,
	pushStateSeparator: "#!",
	cacheIgnore: ["/"],
	showBarsOnPageScrollEnd: false
});

// Add view
var mainView = myApp.addView('.view-main', {
});

(function() {
	$$("article a[href^='http']").addClass("external");
//	checkDisqus();
//	loadBA();
})();

$$(document).on('pageAfterAnimation', '.page', function() {
	$$("article a[href^='http']").addClass("external"); //博文里的外部链接添加class="external"
//	checkDisqus();
//	loadBA();
})
<commit_msg>debug<commit_after>// Export selectors engine
var $$ = Dom7;
//// load js function
//function loadJS(u, c, a = true, i = "") {
//	var d = document,
//		t = 'script',
//		o = d.createElement(t),
//		s = d.getElementsByTagName(t)[0];
//	o.async = a;
//	if (i) o.id = i;
//	o.src = u;
//	if (c) {
//		o.addEventListener('load', function(e) {
//			c(null, e);
//		}, false);
//	}
//	s.parentNode.insertBefore(o, s);
//}
//// load Disqus , it is async now,support spa
//function loadDisqus(commentDom) {
//	var disqus_username=$$('meta[name="disqus_username"]').attr("content");
//	commentDom.html('

');
//	if ($$("script#disqus").length == 0) {
//		loadJS("http://"+disqus_username+".disqus.com/embed.js", function() {
//			var disqus_identifier = commentDom.data("disqus_identifier");
//			var disqus_url = commentDom.data("disqus_url");
//			var disqus_title = commentDom.data("disqus_title");
//			DISQUS.reset({
//				reload: true,
//				config: function() {
//					this.page.identifier = disqus_identifier;
//					this.page.url = disqus_url;
//					this.page.title = disqus_title;
//				}
//			});
//		}, true, "disqus");
//	} else {
//		var disqus_identifier = commentDom.data("disqus_identifier");
//		var disqus_url = commentDom.data("disqus_url");
//		var disqus_title = commentDom.data("disqus_title");
//		DISQUS.reset({
//			reload: true,
//			config: function() {
//				this.page.identifier = disqus_identifier;
//				this.page.url = disqus_url;
//				this.page.title = disqus_title;
//			}
//		});
//	}
//}
//// check whether load Disqus or not, if load,check which commentDom to load to,it is perfect now
//function checkDisqus() {
//	var commentDom = $$(".page").find(".comment");
//	if (commentDom.length > 0) {
//		commentDom.find("#disqus_thread").remove();
//		if (commentDom.length == 1) {
//			if ($$(".view-main").find(".page").length == 1 || $$(".page-from-left-to-center").find(".comment").length > 0 || $$(".page-on-center").find(".comment").length > 0) {
//				loadDisqus(commentDom);
//			}
//		} else {
//			if ($$(".page-from-left-to-center").find(".comment").length > 0) {
//				commentDom = $$(".page-from-left-to-center").find(".comment");
//			}
//			if ($$(".page-on-center").find(".comment").length > 0) {
//				commentDom = $$(".page-on-center").find(".comment");
//			}
//			loadDisqus(commentDom);
//		}
//	}
//}
// load Baidu Analytics
//function loadBA(){
//	$$("script#baidu_analytics").remove();
//	var ba_track_id=$$('meta[name="ba_track_id"]').attr("content");
//	var _hmt = _hmt || [];
//	loadJS("http://hm.baidu.com/hm.js?"+ba_track_id,function(){},true,"baidu_analytics");
//}

function abc(){
	alert("");
}

// Initialize app
var myApp = new Framework7({
	material: true,
	pushState: true,
	pushStateSeparator: "#!",
	cacheIgnore: ["/"],
	showBarsOnPageScrollEnd: false
});

// Add view
var mainView = myApp.addView('.view-main', {
});

(function() {
	$$("article a[href^='http']").addClass("external");abc();
//	checkDisqus();
//	loadBA();
})();

$$(document).on('pageAfterAnimation', '.page', function() {
	$$("article a[href^='http']").addClass("external"); //博文里的外部链接添加class="external"
//	checkDisqus();
//	loadBA();
})
<|endoftext|>


<commit_before>'use strict'

/**
 * @module serverless-plugin-warmup
 *
 * @see {@link https://serverless.com/framework/docs/providers/aws/guide/plugins/}
 *
 * @requires 'bluebird'
 * @requires 'fs-extra'
 * @requires 'path'
 * */
const BbPromise = require('bluebird')
const fs = BbPromise.promisifyAll(require('fs-extra'))
const path = require('path')

/**
 * @classdesc Keep your lambdas warm during Winter
 * @class WarmUP
 * */
class WarmUP {
  /**
   * @description Serverless Warm Up
   * @constructor
   *
   * @param {!Object} serverless - Serverless object
   * @param {!Object} options - Serverless options
   * */
  constructor (serverless, options) {
    /** Serverless variables */
    this.serverless = serverless
    this.options = options

    this.provider = this.serverless.getProvider('aws')

    this.hooks = {
      'after:package:initialize': this.afterPackageInitialize.bind(this),
      'after:package:createDeploymentArtifacts': this.afterCreateDeploymentArtifacts.bind(this),
      'after:deploy:deploy': this.afterDeployFunctions.bind(this)
    }
  }

  /**
   * @description After package initialize hook. Create warmer function and add it to the service.
   *
   * @fulfil {} — Warm up set
   * @reject {Error} Warm up error
   *
   * @return {(boolean|Promise)}
   * */
  afterPackageInitialize () {
    // See https://github.com/serverless/serverless/issues/2631
    this.options.stage  = this.options.stage
      || this.serverless.service.provider.stage
      || (this.serverless.service.defaults && this.serverless.service.defaults.stage)
      || 'dev'
    this.options.region = this.options.region
      || this.serverless.service.provider.region
      || (this.serverless.service.defaults && this.serverless.service.defaults.region)
      || 'us-east-1'
    this.custom = this.serverless.service.custom

    this.configPlugin()
    return this.createWarmer()
  }

  /**
   * @description After create deployment artifacts. Clean prefix folder.
   *
   * @fulfil {} — Optimization finished
   * @reject {Error} Optimization error
   *
   * @return {Promise}
   * */
  afterCreateDeploymentArtifacts () {
    return this.cleanFolder()
  }

  /**
   * @description After deploy functions hooks
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  afterDeployFunctions () {
    this.configPlugin()
    if (this.warmup.prewarm) {
      return this.warmUpFunctions()
    }
  }

  /**
   * @description Configure the plugin based on the context of serverless.yml
   *
   * @return {}
   * */
  configPlugin () {
    /** Set warm up folder, file and handler paths */
    this.folderName = '_warmup'
    if (this.custom && this.custom.warmup && typeof this.custom.warmup.folderName === 'string') {
      this.folderName = this.custom.warmup.folderName
    }
    this.pathFolder = this.getPath(this.folderName)
    this.pathFile = this.pathFolder + '/index.js'
    this.pathHandler = this.folderName + '/index.warmUp'

    /** Default options */
    this.warmup = {
      cleanFolder: true,
      memorySize: 128,
      name: this.serverless.service.service + '-' + this.options.stage + '-warmup-plugin',
      schedule: ['rate(5 minutes)'],
      timeout: 10,
      prewarm: false
    }

    /** Set global custom options */
    if (!this.custom || !this.custom.warmup) {
      return
    }

    /** Clean folder */
    if (typeof this.custom.warmup.cleanFolder === 'boolean') {
      this.warmup.cleanFolder = this.custom.warmup.cleanFolder
    }

    /** Memory size */
    if (typeof this.custom.warmup.memorySize === 'number') {
      this.warmup.memorySize = this.custom.warmup.memorySize
    }

    /** Function name */
    if (typeof this.custom.warmup.name === 'string') {
      this.warmup.name = this.custom.warmup.name
    }

    /** Role */
    if (typeof this.custom.warmup.role === 'string') {
      this.warmup.role = this.custom.warmup.role
    }

    /** Tags */
    if (typeof this.custom.warmup.tags === 'object') {
      this.warmup.tags = this.custom.warmup.tags
    }

    /** Schedule expression */
    if (typeof this.custom.warmup.schedule === 'string') {
      this.warmup.schedule = [this.custom.warmup.schedule]
    } else if (Array.isArray(this.custom.warmup.schedule)) {
      this.warmup.schedule = this.custom.warmup.schedule
    }

    /** Timeout */
    if (typeof this.custom.warmup.timeout === 'number') {
      this.warmup.timeout = this.custom.warmup.timeout
    }

    /** Pre-warm */
    if (typeof this.custom.warmup.prewarm === 'boolean') {
      this.warmup.prewarm = this.custom.warmup.prewarm
    }
  }

  /**
   * @description After create deployment artifacts
   *
   * @param {string} file — File path
   *
   * @return {String} Absolute file path
   * */
  getPath (file) {
    return path.join(this.serverless.config.servicePath, file)
  }

  /**
   * @description Clean prefix folder
   *
   * @fulfil {} — Folder cleaned
   * @reject {Error} File system error
   *
   * @return {Promise}
   * */
  cleanFolder () {
    if (!this.warmup.cleanFolder) {
      return Promise.resolve()
    }
    return fs.removeAsync(this.pathFolder)
  }

  /**
   * @description Warm up functions
   *
   * @fulfil {} — Warm up function created and added to service
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmer () {
    /** Get functions */
    const allFunctions = this.serverless.service.getAllFunctions()

    /** Filter functions for warm up */
    return BbPromise.filter(allFunctions, (functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)

      /** Function needs to be warm */
      if (functionObject.warmup === true ||
        functionObject.warmup === this.options.stage ||
        (Array.isArray(functionObject.warmup) &&
          functionObject.warmup.indexOf(this.options.stage) !== -1)) {
        return functionObject
      }
    }).then((functionNames) => {
      /** Skip writing if no functions need to be warm */
      if (!functionNames.length) {
        /** Log no warmup */
        this.serverless.cli.log('WarmUP: no lambda to warm')
        return true
      }

      /** Write warm up function */
      return this.createWarmUpFunctionArtifact(functionNames)
    }).then((skip) => {
      /** Add warm up function to service */
      if (skip !== true) {
        return this.addWarmUpFunctionToService()
      }
    })
  }

  /**
   * @description Write warm up ES6 function
   *
   * @param {Array} functionNames - Function names
   *
   * @fulfil {} — Warm up function created
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmUpFunctionArtifact (functionNames) {
    /** Log warmup start */
    this.serverless.cli.log('WarmUP: setting ' + functionNames.length + ' lambdas to be warm')

    /** Get function names */
    functionNames = functionNames.map((functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)
      this.serverless.cli.log('WarmUP: ' + functionObject.name)
      return functionObject.name
    })

    /** Write function invoke promises and push to array */
    const warmUpFunction = `"use strict";

/** Generated by Serverless WarmUP Plugin at ${new Date().toISOString()} */
const aws = require("aws-sdk");
aws.config.region = "${this.options.region}";
const lambda = new aws.Lambda();
const functionNames = "${functionNames.join()}".split(",");
module.exports.warmUp = (event, context, callback) => {
  let invokes = [];
  let errors = 0;
  console.log("Warm Up Start");
  functionNames.forEach((functionName) => {
    const params = {
      // base64 encoded: {"custom":{"warmupEvent":"1"}}
      ClientContext: "eyJjdXN0b20iOnsid2FybXVwRXZlbnQiOiIxIn19",
      FunctionName: functionName,
      InvocationType: "RequestResponse",
      LogType: "None",
      Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
      Payload: JSON.stringify({ source: "serverless-plugin-warmup" })
    };
    invokes.push(lambda.invoke(params).promise().then((data) => {
      console.log("Warm Up Invoke Success: " + functionName, data);
    }, (error) => {
      errors++;
      console.log("Warm Up Invoke Error: " + functionName, error);
    }));
  });
  Promise.all(invokes).then(() => {
    console.log("Warm Up Finished with " + errors + " invoke errors");
    callback();
  });
}`

    /** Write warm up file */
    return fs.outputFileAsync(this.pathFile, warmUpFunction)
  }

  /**
   * @description Add warm up function to service
   *
   * @return {Object} Warm up service function object
   * */
  addWarmUpFunctionToService () {
    /** SLS warm up function */
    this.serverless.service.functions.warmUpPlugin = {
      description: 'Serverless WarmUP Plugin',
      events: this.warmup.schedule.map(schedule => ({ schedule })),
      handler: this.pathHandler,
      memorySize: this.warmup.memorySize,
      name: this.warmup.name,
      runtime: 'nodejs6.10',
      package: {
        individually: true,
        exclude: ['**'],
        include: [this.folderName + '/**']
      },
      timeout: this.warmup.timeout
    }

    if (this.warmup.role) {
      this.serverless.service.functions.warmUpPlugin.role = this.warmup.role
    }

    if (this.warmup.tags) {
      this.serverless.service.functions.warmUpPlugin.tags = this.warmup.tags
    }

    /** Return service function object */
    return this.serverless.service.functions.warmUpPlugin
  }

  /**
   * @description Warm up the functions immediately after deployment
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  warmUpFunctions () {
    this.serverless.cli.log('WarmUP: Pre-warming up your functions')

    const params = {
      FunctionName: this.warmup.name,
      InvocationType: 'RequestResponse',
      LogType: 'None',
      Qualifier: process.env.SERVERLESS_ALIAS || '$LATEST',
      Payload: JSON.stringify({ source: 'serverless-plugin-warmup' })
    }

    return this.provider.request('Lambda', 'invoke', params)
      .then(data => this.serverless.cli.log('WarmUp: Functions sucessfuly pre-warmed'))
      .catch(error => this.serverless.cli.log('WarmUp: Error while pre-warming functions', error))
  }
}

/** Export WarmUP class */
module.exports = WarmUP
<commit_msg>Use same payload for ClientContext & Payload<commit_after>'use strict'

/**
 * @module serverless-plugin-warmup
 *
 * @see {@link https://serverless.com/framework/docs/providers/aws/guide/plugins/}
 *
 * @requires 'bluebird'
 * @requires 'fs-extra'
 * @requires 'path'
 * */
const BbPromise = require('bluebird')
const fs = BbPromise.promisifyAll(require('fs-extra'))
const path = require('path')

/**
 * @classdesc Keep your lambdas warm during Winter
 * @class WarmUP
 * */
class WarmUP {
  /**
   * @description Serverless Warm Up
   * @constructor
   *
   * @param {!Object} serverless - Serverless object
   * @param {!Object} options - Serverless options
   * */
  constructor (serverless, options) {
    /** Serverless variables */
    this.serverless = serverless
    this.options = options

    this.provider = this.serverless.getProvider('aws')

    this.hooks = {
      'after:package:initialize': this.afterPackageInitialize.bind(this),
      'after:package:createDeploymentArtifacts': this.afterCreateDeploymentArtifacts.bind(this),
      'after:deploy:deploy': this.afterDeployFunctions.bind(this)
    }
  }

  /**
   * @description After package initialize hook. Create warmer function and add it to the service.
   *
   * @fulfil {} — Warm up set
   * @reject {Error} Warm up error
   *
   * @return {(boolean|Promise)}
   * */
  afterPackageInitialize () {
    // See https://github.com/serverless/serverless/issues/2631
    this.options.stage = this.options.stage
      || this.serverless.service.provider.stage
      || (this.serverless.service.defaults && this.serverless.service.defaults.stage)
      || 'dev'
    this.options.region = this.options.region
      || this.serverless.service.provider.region
      || (this.serverless.service.defaults && this.serverless.service.defaults.region)
      || 'us-east-1'
    this.custom = this.serverless.service.custom

    this.configPlugin()
    return this.createWarmer()
  }

  /**
   * @description After create deployment artifacts. Clean prefix folder.
   *
   * @fulfil {} — Optimization finished
   * @reject {Error} Optimization error
   *
   * @return {Promise}
   * */
  afterCreateDeploymentArtifacts () {
    return this.cleanFolder()
  }

  /**
   * @description After deploy functions hooks
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  afterDeployFunctions () {
    this.configPlugin()
    if (this.warmup.prewarm) {
      return this.warmUpFunctions()
    }
  }

  /**
   * @description Configure the plugin based on the context of serverless.yml
   *
   * @return {}
   * */
  configPlugin () {
    /** Set warm up folder, file and handler paths */
    this.folderName = '_warmup'
    if (this.custom && this.custom.warmup && typeof this.custom.warmup.folderName === 'string') {
      this.folderName = this.custom.warmup.folderName
    }
    this.pathFolder = this.getPath(this.folderName)
    this.pathFile = this.pathFolder + '/index.js'
    this.pathHandler = this.folderName + '/index.warmUp'
    this.payload = JSON.stringify({ source: 'serverless-plugin-warmup' })

    /** Default options */
    this.warmup = {
      cleanFolder: true,
      memorySize: 128,
      name: this.serverless.service.service + '-' + this.options.stage + '-warmup-plugin',
      schedule: ['rate(5 minutes)'],
      timeout: 10,
      prewarm: false
    }

    /** Set global custom options */
    if (!this.custom || !this.custom.warmup) {
      return
    }

    /** Clean folder */
    if (typeof this.custom.warmup.cleanFolder === 'boolean') {
      this.warmup.cleanFolder = this.custom.warmup.cleanFolder
    }

    /** Memory size */
    if (typeof this.custom.warmup.memorySize === 'number') {
      this.warmup.memorySize = this.custom.warmup.memorySize
    }

    /** Function name */
    if (typeof this.custom.warmup.name === 'string') {
      this.warmup.name = this.custom.warmup.name
    }

    /** Role */
    if (typeof this.custom.warmup.role === 'string') {
      this.warmup.role = this.custom.warmup.role
    }

    /** Tags */
    if (typeof this.custom.warmup.tags === 'object') {
      this.warmup.tags = this.custom.warmup.tags
    }

    /** Schedule expression */
    if (typeof this.custom.warmup.schedule === 'string') {
      this.warmup.schedule = [this.custom.warmup.schedule]
    } else if (Array.isArray(this.custom.warmup.schedule)) {
      this.warmup.schedule = this.custom.warmup.schedule
    }

    /** Timeout */
    if (typeof this.custom.warmup.timeout === 'number') {
      this.warmup.timeout = this.custom.warmup.timeout
    }

    /** Pre-warm */
    if (typeof this.custom.warmup.prewarm === 'boolean') {
      this.warmup.prewarm = this.custom.warmup.prewarm
    }
  }

  /**
   * @description After create deployment artifacts
   *
   * @param {string} file — File path
   *
   * @return {String} Absolute file path
   * */
  getPath (file) {
    return path.join(this.serverless.config.servicePath, file)
  }

  /**
   * @description Clean prefix folder
   *
   * @fulfil {} — Folder cleaned
   * @reject {Error} File system error
   *
   * @return {Promise}
   * */
  cleanFolder () {
    if (!this.warmup.cleanFolder) {
      return Promise.resolve()
    }
    return fs.removeAsync(this.pathFolder)
  }

  /**
   * @description Warm up functions
   *
   * @fulfil {} — Warm up function created and added to service
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmer () {
    /** Get functions */
    const allFunctions = this.serverless.service.getAllFunctions()

    /** Filter functions for warm up */
    return BbPromise.filter(allFunctions, (functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)

      /** Function needs to be warm */
      if (functionObject.warmup === true ||
        functionObject.warmup === this.options.stage ||
        (Array.isArray(functionObject.warmup) &&
          functionObject.warmup.indexOf(this.options.stage) !== -1)) {
        return functionObject
      }
    }).then((functionNames) => {
      /** Skip writing if no functions need to be warm */
      if (!functionNames.length) {
        /** Log no warmup */
        this.serverless.cli.log('WarmUP: no lambda to warm')
        return true
      }

      /** Write warm up function */
      return this.createWarmUpFunctionArtifact(functionNames)
    }).then((skip) => {
      /** Add warm up function to service */
      if (skip !== true) {
        return this.addWarmUpFunctionToService()
      }
    })
  }

  /**
   * @description Write warm up ES6 function
   *
   * @param {Array} functionNames - Function names
   *
   * @fulfil {} — Warm up function created
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmUpFunctionArtifact (functionNames) {
    /** Log warmup start */
    this.serverless.cli.log('WarmUP: setting ' + functionNames.length + ' lambdas to be warm')

    /** Get function names */
    functionNames = functionNames.map((functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)
      this.serverless.cli.log('WarmUP: ' + functionObject.name)
      return functionObject.name
    })

    /** Write function invoke promises and push to array */
    const warmUpFunction = `"use strict";

/** Generated by Serverless WarmUP Plugin at ${new Date().toISOString()} */
const aws = require("aws-sdk");
aws.config.region = "${this.options.region}";
const lambda = new aws.Lambda();
const functionNames = "${functionNames.join()}".split(",");
module.exports.warmUp = (event, context, callback) => {
  let invokes = [];
  let errors = 0;
  console.log("Warm Up Start");
  functionNames.forEach((functionName) => {
    const params = {
      ClientContext: "${Buffer.from(`{"custom":${this.payload}}`).toString('base64')}",
      FunctionName: functionName,
      InvocationType: "RequestResponse",
      LogType: "None",
      Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
      Payload: ${this.payload}
    };
    invokes.push(lambda.invoke(params).promise().then((data) => {
      console.log("Warm Up Invoke Success: " + functionName, data);
    }, (error) => {
      errors++;
      console.log("Warm Up Invoke Error: " + functionName, error);
    }));
  });
  Promise.all(invokes).then(() => {
    console.log("Warm Up Finished with " + errors + " invoke errors");
    callback();
  });
}`

    /** Write warm up file */
    return fs.outputFileAsync(this.pathFile, warmUpFunction)
  }

  /**
   * @description Add warm up function to service
   *
   * @return {Object} Warm up service function object
   * */
  addWarmUpFunctionToService () {
    /** SLS warm up function */
    this.serverless.service.functions.warmUpPlugin = {
      description: 'Serverless WarmUP Plugin',
      events: this.warmup.schedule.map(schedule => ({ schedule })),
      handler: this.pathHandler,
      memorySize: this.warmup.memorySize,
      name: this.warmup.name,
      runtime: 'nodejs6.10',
      package: {
        individually: true,
        exclude: ['**'],
        include: [this.folderName + '/**']
      },
      timeout: this.warmup.timeout
    }

    if (this.warmup.role) {
      this.serverless.service.functions.warmUpPlugin.role = this.warmup.role
    }

    if (this.warmup.tags) {
      this.serverless.service.functions.warmUpPlugin.tags = this.warmup.tags
    }

    /** Return service function object */
    return this.serverless.service.functions.warmUpPlugin
  }

  /**
   * @description Warm up the functions immediately after deployment
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  warmUpFunctions () {
    this.serverless.cli.log('WarmUP: Pre-warming up your functions')

    const params = {
      FunctionName: this.warmup.name,
      InvocationType: 'RequestResponse',
      LogType: 'None',
      Qualifier: process.env.SERVERLESS_ALIAS || '$LATEST',
      Payload: JSON.stringify({ source: 'serverless-plugin-warmup' })
    }

    return this.provider.request('Lambda', 'invoke', params)
      .then(data => this.serverless.cli.log('WarmUp: Functions sucessfuly pre-warmed'))
      .catch(error => this.serverless.cli.log('WarmUp: Error while pre-warming functions', error))
  }
}

/** Export WarmUP class */
module.exports = WarmUP
<|endoftext|>


<commit_before>(function() {

  var world, data, grid_regions, top_left, bottom_right, dims
    , height = window.innerHeight
    , width = window.innerWidth
    , current_year = 1979
    , sens = 1
    , _time = 0
    //, start_year = 1979
    //, end_year = 2012
    //, _scen = 0
    //, _irr = 0
    , resize_time
    , resize_timeout = false
    , resize_delta = 200
    , resize_reload = false

    , svg = d3.select('#map').append('svg')
      .attr({'width': width, 'height': height})
      .append('g')
    , ocean_layer = svg.append('g')
      .attr('id', 'ocean_layer')
    , grid_layer = svg.append('g')
      .attr('id', 'grid_layer')
    , edges_layer = svg.append('g')
      .attr('id', 'edges_layer')

    , color = d3.scale.quantile()
      .range(['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c',
              '#f16913', '#d94801', '#a63603', '#7f2704'])

    , projection = d3.geo.equirectangular()
      .rotate([-Options.lon, 0])
      .center([0, Options.lat])
      .scale(height * 2)
      .translate([width / 2, height / 2])
      .precision(.1)
    , path = d3.geo.path()
      .projection(projection)
    , graticule = d3.geo.graticule()

    , hover_legend = d3.select('#hover_legend')
    ;

  var dragged = function dragged() {

    var λ = d3.event.dx * sens
      , φ = d3.event.dy * sens
      , upper_drag_limit = projection([0, 90])[1]
      , lower_drag_limit = projection([0, -90])[1] - height
    ;

    φ = -φ > lower_drag_limit ? -lower_drag_limit
      : -φ < upper_drag_limit ? -upper_drag_limit
      : φ;

    var c = projection.invert([
      width / 2 - λ,
      height / 2 - φ]);

    projection
      .rotate([-c[0], 0])
      .center([0, c[1]]);
    svg.selectAll('.boundary').attr('d', path);
  };

  var dragend = function dragend() {
    get_data_for_viewport();
  };

  var drag_rotate = d3.behavior.drag()
      .origin(function() {
        var r = projection.rotate();
        return {x: r[0] / sens, y: -r[1] / sens}; })
      .on('drag', dragged)
      .on('dragend', dragend)
    , scroll_zoom = d3.behavior.zoom()
      .translate(projection.translate())
      .scale(projection.scale())
      .scaleExtent([height, 8 * height])
      .on('zoom', null)
    ;

  var update_projection = function update_projection(w, h, d) {
    return (width / 6) * 360 / (42);
  };

  var expand_lon = function expand_lon(lon, left) {
    while (lon < left) {
      lon += 180;
    }
    return lon;
  };

  var compress_lon = function compress_lon(lon) {
    return (lon / 180) % 1 * 180;
  };

  var limit_lat = function limit_lat(lat) {

  };

  var get_viewport_dimensions = function get_viewport_dimensions() {
    top_left = projection.invert([0,0]);
    bottom_right = projection.invert([width, height]);

    top_left[0] = bottom_right[0] > 180 ? top_left[0] - 180 : top_left[0];
    bottom_right[0] = bottom_right[0] > 180 ? bottom_right[0] - 180 : bottom_right[0];

    top_right = [bottom_right[0], top_left[1]];
    bottom_left = [top_left[0], bottom_right[1]];
    center = [
      compress_lon((
        expand_lon(bottom_right[0], top_left[0]) - top_left[0])
        / 2 + top_left[0]),
      (top_left[1] - bottom_right[1]) / 2 + bottom_right[1]
    ];

    return {
      'top_left': top_left,
      'top_right': top_right,
      'bottom_left': bottom_left,
      'bottom_right': bottom_right,
      'center': center
    }
  };

  var resize = function resize() {
    resize_time = new Date();
    if (resize_timeout === false) {
      resize_timeout = true;
      setTimeout(resize_end, resize_delta);
    }
    width = window.innerWidth;
    height = window.innerHeight;
    d3.select('svg').attr({height: height, width: width});
    resize_reload = height * 2 < projection.scale();
    projection.translate([width / 2, height / 2])
      .scale(height * 2);
    d3.selectAll('.boundary').attr('d', path);
  };

  var resize_end = function resize_end() {
    if (new Date() - resize_time < resize_delta) {
      setTimeout(resize_end, resize_delta);
    } else {
      resize_timeout = false;
      if (resize_reload) {
        get_data_for_viewport();
      }
    }
  };

  var show_loader = function show_loader() {
    var loader = d3.select('#loader');
    loader.style({
      display: 'block',
      top: (height - loader.node().getBoundingClientRect().height) / 2 + 'px',
      left: (width - loader.node().getBoundingClientRect().width) / 2 + 'px'
    });
  };

  var hide_loader = function show_loader() {
    var loader = d3.select('#loader');
    loader.style({ display: 'none' });
  };

  var draw_map_basics = function draw_map_basics() {

    d3.json('/static/json/countries_110.geojson', function(world) {

      var sphere = [
        ocean_layer.append('path')
          .datum({type: 'Sphere'})
          .attr('id', 'sphere')
          .attr('d', path)
          .attr('class', 'boundary'),
        ocean_layer.append('use')
          .attr('class', 'stroke')
          .attr('xlink:href', '#sphere')
      ];

      ocean_layer.append('path')
        .datum(graticule)
        .attr('class', 'graticule boundary')
        .attr('d', path)
        .style({
          stroke: '#B4D5E5',
          'stroke-width': '1px',
          fill: 'transparent'
        });

      ocean_layer.selectAll('path.countries')
        .data(world.features)
        .enter()
        .append('path')
        .attr('d', path)
        .attr('class', 'countries boundary')
        .style({
          stroke: 'none',
          fill: '#dddddd'
        });

      edges_layer.selectAll('path.countries')
        .data(world.features)
        .enter()
        .append('path')
        .attr('d', path)
        .attr('class', 'countries boundary')
        .style({
          stroke: 'black',
          'stroke-width': 1,
          'stroke-line-join': 'round',
          fill: 'none'
        });

    });

  };

  var update_data_fills = function update_data_fills() {
    grid_regions.each(function(d, i) {
      d3.select(this).style({
        fill: function() {
          return d.properties.value.values[_time] == null
            ? 'transparent' : color(d.properties.value.values[_time]);
        }
      });
    });
  };

  var grid_hover = function grid_hover(d) {
    var q = '[' + (d.geometry.coordinates[0][0][0] +.25) + ', ';
    q += (d.geometry.coordinates[0][0][1] +.25) + '] ';
    q += (Math.round(d.properties.value.values[_time] * 100) / 100) + '' ;
    hover_legend.select('p').html(q);
    hover_legend.style({
      left: d3.mouse(this)[0] + 'px',
      top: d3.mouse(this)[1] + 'px',
      display: 'block'
    });
    hover_legend.classed('hovered', true);
  };

  var get_data_for_viewport = function get_data_for_viewport() {

    show_loader();
    dims = get_viewport_dimensions();

    queue()
      .defer(d3.json, '/api/'+
        dims['top_left'][0]+'/'+ dims['top_left'][1]+'/'+
        dims['bottom_right'][0]+'/'+dims['bottom_right'][1])
      .awaitAll(atlas);
  };

  var atlas = function atlas(error, queued_data) {

    data = queued_data[0];
    data.filter(function (d) { return d.properties.value != null; });
    data.forEach(function(d) {
      d.geometry.coordinates.reverse();
    });

    color.domain([
      d3.min(data, function(d) {
        return d3.min(d.properties.value.values, function(dd) {return dd; }); }),
      d3.max(data, function(d) {
        return d3.max(d.properties.value.values, function(dd) {return dd; }); })]);

     grid_regions = grid_layer.selectAll('.grid-boundary')
      .data(data);
    grid_regions.enter()
      .append('path')
      .attr('class', 'grid-boundary boundary')
      .attr('d', path)
      .on('mouseover', grid_hover)
      .on('mouseout', function() {
        hover_legend.style({display: 'none'});
        hover_legend.classed('hovered', false);})
    ;

    grid_regions.exit().remove();

    update_data_fills(data);
    svg.call(drag_rotate);

    svg.selectAll('.boundary').attr('d', path);
    hide_loader();

  };

  var time_opt = d3.select('#time_select');
  var time_label = d3.select('#menu_time label');
  time_opt.on('input', function() {
    _time = +d3.select(this).property('value');
    //var _ctime = time_label.text();
    current_year = 1979 + _time;
    //time_label.text(current_year);
    //d3.select('#corner_legend [data-type="time"]').text(current_year);
    update_data_fills(data);
  });
  d3.select(window).on('resize', resize);

  get_data_for_viewport();

  draw_map_basics();

})();<commit_msg>Force larger projection scale<commit_after>(function() {

  var world, data, grid_regions, top_left, bottom_right, dims
    , height = window.innerHeight
    , width = window.innerWidth
    , current_year = 1979
    , sens = 1
    , _time = 0
    //, start_year = 1979
    //, end_year = 2012

    , resize_time
    , resize_timeout = false
    , resize_delta = 200
    , resize_reload = false

    , svg = d3.select('#map').append('svg')
      .attr({'width': width, 'height': height})
      .append('g')
    , ocean_layer = svg.append('g')
      .attr('id', 'ocean_layer')
    , grid_layer = svg.append('g')
      .attr('id', 'grid_layer')
    , edges_layer = svg.append('g')
      .attr('id', 'edges_layer')

    , color = d3.scale.quantile()
      .range(['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c',
              '#f16913', '#d94801', '#a63603', '#7f2704'])

    , get_scale = function get_scale() { return d3.max([height, width]); }

    , projection = d3.geo.equirectangular()
      .rotate([-Options.lon, 0])
      .center([0, Options.lat])
      .scale(get_scale())
      .translate([width / 2, height / 2])
      .precision(.1)
    , path = d3.geo.path()
      .projection(projection)
    , graticule = d3.geo.graticule()

    , hover_legend = d3.select('#hover_legend')
    ;

  var drag_rotate = d3.behavior.drag()
      .origin(function() {
        var r = projection.rotate();
        return {x: r[0] / sens, y: -r[1] / sens}; })
      .on('dragstart', drag_start)
      .on('drag', dragged)
      .on('dragend', drag_end)
    , scroll_zoom = d3.behavior.zoom()
      .translate(projection.translate())
      .scale(projection.scale())
      .scaleExtent([height, 8 * height])
      .on('zoom', null)
    ;

  var drag_start = function drag_start() {

  };

  var dragged = function dragged() {

    var λ = d3.event.dx * sens
      , φ = d3.event.dy * sens
      , upper_drag_limit = projection([0, 90])[1]
      , lower_drag_limit = projection([0, -90])[1] - height
    ;

    φ = -φ > lower_drag_limit ? -lower_drag_limit
      : -φ < upper_drag_limit ? -upper_drag_limit
      : φ;

    var c = projection.invert([
      width / 2 - λ,
      height / 2 - φ]);

    projection
      .rotate([-c[0], 0])
      .center([0, c[1]]);
    svg.selectAll('.boundary').attr('d', path);
  };

  var drag_end = function drag_end() {
    grid_regions.remove();
    get_data_for_viewport();
  };

  var get_viewport_dimensions = function get_viewport_dimensions() {

    top_left = projection.invert([0,0]);
    bottom_right = projection.invert([width, height]);

    top_left[0] = bottom_right[0] > 180 ? top_left[0] - 180 : top_left[0];
    bottom_right[0] = bottom_right[0] > 180 ? bottom_right[0] - 180 : bottom_right[0];

    top_right = [bottom_right[0], top_left[1]];
    bottom_left = [top_left[0], bottom_right[1]];

    return {
      'top_left': top_left,
      'top_right': top_right,
      'bottom_left': bottom_left,
      'bottom_right': bottom_right
    }
  };

  var resize = function resize() {

    //Check for end of resize event
    resize_time = new Date();
    if (resize_timeout === false) {
      resize_timeout = true;
      setTimeout(resize_end, resize_delta);
    }

    //Resize SVG
    width = window.innerWidth;
    height = window.innerHeight;
    d3.select('svg').attr({height: height, width: width});

    //Set reload switch
    resize_reload = get_scale() < projection.scale();

    //Re-project
    projection.translate([width / 2, height / 2])
      .scale(get_scale());
    d3.selectAll('.boundary').attr('d', path);
  };

  var resize_end = function resize_end() {
    if (new Date() - resize_time < resize_delta) {
      setTimeout(resize_end, resize_delta);
    } else {
      resize_timeout = false;
      if (resize_reload) {
        get_data_for_viewport();
      }
    }
  };

  var show_loader = function show_loader() {
    var loader = d3.select('#loader');
    loader.style({
      display: 'block',
      top: (height - loader.node().getBoundingClientRect().height) / 2 + 'px',
      left: (width - loader.node().getBoundingClientRect().width) / 2 + 'px'
    });
  };

  var hide_loader = function show_loader() {
    var loader = d3.select('#loader');
    loader.style({ display: 'none' });
  };

  var draw_map_basics = function draw_map_basics() {

    d3.json('/static/json/countries_110.geojson', function(world) {

      var sphere = [
        ocean_layer.append('path')
          .datum({type: 'Sphere'})
          .attr('id', 'sphere')
          .attr('d', path)
          .attr('class', 'boundary'),
        ocean_layer.append('use')
          .attr('class', 'stroke')
          .attr('xlink:href', '#sphere')
      ];

      ocean_layer.append('path')
        .datum(graticule)
        .attr('class', 'graticule boundary')
        .attr('d', path)
        .style({
          stroke: '#B4D5E5',
          'stroke-width': '1px',
          fill: 'transparent'
        });

      ocean_layer.selectAll('path.countries')
        .data(world.features)
        .enter()
        .append('path')
        .attr('d', path)
        .attr('class', 'countries boundary')
        .style({
          stroke: 'none',
          fill: '#dddddd'
        });

      edges_layer.selectAll('path.countries')
        .data(world.features)
        .enter()
        .append('path')
        .attr('d', path)
        .attr('class', 'countries boundary')
        .style({
          stroke: 'black',
          'stroke-width': 1,
          'stroke-line-join': 'round',
          fill: 'none'
        });

    });

  };

  var update_data_fills = function update_data_fills() {
    grid_regions.each(function(d, i) {
      d3.select(this).style({
        fill: function() {
          return d.properties.value.values[_time] == null
            ? 'transparent' : color(d.properties.value.values[_time]);
        }
      });
    });
  };

  var grid_hover = function grid_hover(d) {
    var q = '[' + (d.geometry.coordinates[0][0][0] +.25) + ', ';
    q += (d.geometry.coordinates[0][0][1] +.25) + '] ';
    q += (Math.round(d.properties.value.values[_time] * 100) / 100) + '' ;
    hover_legend.select('p').html(q);
    hover_legend.style({
      left: d3.mouse(this)[0] + 'px',
      top: d3.mouse(this)[1] + 'px',
      display: 'block'
    });
    hover_legend.classed('hovered', true);
  };

  var get_data_for_viewport = function get_data_for_viewport() {

    show_loader();
    dims = get_viewport_dimensions();

    queue()
      .defer(d3.json, '/api/'+
        dims['top_left'][0]+'/'+ dims['top_left'][1]+'/'+
        dims['bottom_right'][0]+'/'+dims['bottom_right'][1])
      .awaitAll(atlas);
  };

  var atlas = function atlas(error, queued_data) {

    data = queued_data[0];
    data.filter(function (d) { return d.properties.value != null; });
    data.forEach(function(d) {
      d.geometry.coordinates.reverse();
    });

    color.domain([
      d3.min(data, function(d) {
        return d3.min(d.properties.value.values, function(dd) {return dd; }); }),
      d3.max(data, function(d) {
        return d3.max(d.properties.value.values, function(dd) {return dd; }); })]);

     grid_regions = grid_layer.selectAll('.grid-boundary')
      .data(data);
    grid_regions.enter()
      .append('path')
      .attr('class', 'grid-boundary boundary')
      .attr('d', path)
      .on('mouseover', grid_hover)
      .on('mouseout', function() {
        hover_legend.style({display: 'none'});
        hover_legend.classed('hovered', false);})
    ;

    grid_regions.exit().remove();

    update_data_fills(data);
    svg.call(drag_rotate);

    svg.selectAll('.boundary').attr('d', path);
    hide_loader();

  };

  var time_opt = d3.select('#time_select');
  var time_label = d3.select('#menu_time label');
  time_opt.on('input', function() {
    _time = +d3.select(this).property('value');
    //var _ctime = time_label.text();
    current_year = 1979 + _time;
    //time_label.text(current_year);
    //d3.select('#corner_legend [data-type="time"]').text(current_year);
    update_data_fills(data);
  });
  d3.select(window).on('resize', resize);

  get_data_for_viewport();

  draw_map_basics();

})();<|endoftext|>


<commit_before>require('es6-shim/es6-shim');
var stackTrace = require('stack-trace');
var fs = require('fs');
var path = require('path');
var sourceMap = require("source-map");

class ParsedError {
    constructor(err) {
        this.name = err.name;
        this.message = err.message;
        this.originalStack = err.stack;
    }

    toString() {
        return this.name + ': ' + this.message + "\n" + this.stack.toString();
    }
}

class StackTrace {
    constructor() {
        this.items = [];
    }

    forEach() {
        return this.items.forEach.apply(this.items, arguments);
    }

    toString() {
        var str = '';
        this.render(function(string) {
            str += string + "\n";
        });
        return str;
    }

    render(log) {
        this.forEach((line) => {
            var fullPath = line.fileName + ':' + line.lineNumber + ':' + line.columnNumber;
            log(
                '    at '
                 + ( line.methodName || line.typeName ? (line.typeName && line.typeName + '.')
                 + (line.methodName || '<anonymous>')
                 + ' (' + fullPath + ')' : fullPath));
            //line.native
        });
    }
}

class StackTraceItem {
    constructor(item) {
        this.fileName = item.fileName;
        this.lineNumber = item.lineNumber;
        this.columnNumber = item.columnNumber;
        this.typeName = item.typeName;
        this.methodName = item.methodName;
        this.native = item.native;
        this.file = item.file;
    }

    getFileName() {
        return this.fileName;
    }
    getLineNumber() {
        return this.line;
    }
    getColumnNumber() {
        return this.column + 1;
    }
    getScriptNameOrSourceURL() {
        return this.fileName;
    }
}

/**
 * Parse an error and extract its stack trace
 * @param  {Error} err
 * @return {StackTrace}
 */
exports.parse = function(err) {
    var parsedError = new ParsedError(err);
    parsedError.stack = exports.parseErrorStack(err);
    return parsedError;
};

exports.parseErrorStack = function(err) {
    var finalStack = new StackTrace();
    var stack = stackTrace.parse(err);

    var files = new Map();
    stack.forEach((line) => {
        if (!line.fileName || files.has(line.fileName)) {
            return;
        }
        files.set(line.fileName, {});
    });

    files.forEach((file, fileName) => {
        if (fileName.startsWith('/')) {
            try {
                var fileNameMap = fileName + '.map';
                var fileContent = fs.readFileSync(fileName).toString();
                var match = /\/\/[#@]\s*sourceMappingURL=(.*)\s*$/m.exec(fileContent);
                if (match && match[1] && match[1][0] === '/') {
                    fileNameMap = match[1];
                }
                var contents = fs.readFileSync(fileNameMap).toString();
                file.map = new sourceMap.SourceMapConsumer(contents);
                if (file.map.sourcesContent) {
                    var sourceIndex = file.map.sources.indexOf(file.map.file);
                    file.contents = sourceIndex !== -1 && file.map.sourcesContent[sourceIndex];
                }
                if (!file.contents) {
                    var sourceRoot = path.resolve(path.dirname(fileName), file.map.sourceRoot);
                    if (sourceRoot.slice(-1) !== '/') {
                        sourceRoot += '/';
                    }
                    file.sourceFileName = sourceRoot + file.map.file;
                    file.contents = fs.readFileSync(file.sourceFileName).toString();
                }
                // TODO lazy loading
                //, path.resolve(file.map.sourceRoot, original.source)
            } catch(e) {
                //console.log(e.stack);
            }
        }
    });

    stack.forEach((line) => {
        var file = files.get(line.fileName);
        if (file && file.map) {
            var original = file.map.originalPositionFor({ line: line.lineNumber, column: line.columnNumber });
            if (original.source) {
                //, path.resolve(file.map.sourceRoot, original.source)
                line.fileName = file.sourceFileName;
                line.lineNumber = original.line;
                line.columnNumber = original.column;
                if (original.name) {
                    line.methodName = original.name;
                }
            }
            line.file = file;
        }
        finalStack.items.push(new StackTraceItem(line));
    });

    return finalStack;
};

/**
 * Parse then log an error with logger.error
 * @param  {Error} err
 */
exports.log = function(err) {
    /* global logger */
    var parsedError = exports.parse(err);
    logger.error(parsedError.toString());
};<commit_msg>jsdoc<commit_after>require('es6-shim/es6-shim');
var stackTrace = require('stack-trace');
var fs = require('fs');
var path = require('path');
var sourceMap = require("source-map");

class ParsedError {
    constructor(err) {
        this.name = err.name;
        this.message = err.message;
        this.originalStack = err.stack;
    }

    toString() {
        return this.name + ': ' + this.message + "\n" + this.stack.toString();
    }
}

class StackTrace {
    constructor() {
        this.items = [];
    }

    forEach() {
        return this.items.forEach.apply(this.items, arguments);
    }

    toString() {
        var str = '';
        this.render(function(string) {
            str += string + "\n";
        });
        return str;
    }

    render(log) {
        this.forEach((line) => {
            var fullPath = line.fileName + ':' + line.lineNumber + ':' + line.columnNumber;
            log(
                '    at '
                 + ( line.methodName || line.typeName ? (line.typeName && line.typeName + '.')
                 + (line.methodName || '<anonymous>')
                 + ' (' + fullPath + ')' : fullPath));
            //line.native
        });
    }
}

class StackTraceItem {
    constructor(item) {
        this.fileName = item.fileName;
        this.lineNumber = item.lineNumber;
        this.columnNumber = item.columnNumber;
        this.typeName = item.typeName;
        this.methodName = item.methodName;
        this.native = item.native;
        this.file = item.file;
    }

    getFileName() {
        return this.fileName;
    }
    getLineNumber() {
        return this.line;
    }
    getColumnNumber() {
        return this.column + 1;
    }
    getScriptNameOrSourceURL() {
        return this.fileName;
    }
}

/**
 * Parse an error and extract its stack trace
 * @param  {Error} err
 * @return {ParsedError}
 */
exports.parse = function(err) {
    var parsedError = new ParsedError(err);
    parsedError.stack = exports.parseErrorStack(err);
    return parsedError;
};

/**
 * Parse an error and extract its stack trace
 * @param  {Error} err
 * @return {StackTrace}
 */
exports.parseErrorStack = function(err) {
    var finalStack = new StackTrace();
    var stack = stackTrace.parse(err);

    var files = new Map();
    stack.forEach((line) => {
        if (!line.fileName || files.has(line.fileName)) {
            return;
        }
        files.set(line.fileName, {});
    });

    files.forEach((file, fileName) => {
        if (fileName.startsWith('/')) {
            try {
                var fileNameMap = fileName + '.map';
                var fileContent = fs.readFileSync(fileName).toString();
                var match = /\/\/[#@]\s*sourceMappingURL=(.*)\s*$/m.exec(fileContent);
                if (match && match[1] && match[1][0] === '/') {
                    fileNameMap = match[1];
                }
                var contents = fs.readFileSync(fileNameMap).toString();
                file.map = new sourceMap.SourceMapConsumer(contents);
                if (file.map.sourcesContent) {
                    var sourceIndex = file.map.sources.indexOf(file.map.file);
                    file.contents = sourceIndex !== -1 && file.map.sourcesContent[sourceIndex];
                }
                if (!file.contents) {
                    var sourceRoot = path.resolve(path.dirname(fileName), file.map.sourceRoot);
                    if (sourceRoot.slice(-1) !== '/') {
                        sourceRoot += '/';
                    }
                    file.sourceFileName = sourceRoot + file.map.file;
                    file.contents = fs.readFileSync(file.sourceFileName).toString();
                }
                // TODO lazy loading
                //, path.resolve(file.map.sourceRoot, original.source)
            } catch(e) {
                //console.log(e.stack);
            }
        }
    });

    stack.forEach((line) => {
        var file = files.get(line.fileName);
        if (file && file.map) {
            var original = file.map.originalPositionFor({ line: line.lineNumber, column: line.columnNumber });
            if (original.source) {
                //, path.resolve(file.map.sourceRoot, original.source)
                line.fileName = file.sourceFileName;
                line.lineNumber = original.line;
                line.columnNumber = original.column;
                if (original.name) {
                    line.methodName = original.name;
                }
            }
            line.file = file;
        }
        finalStack.items.push(new StackTraceItem(line));
    });

    return finalStack;
};

/**
 * Parse then log an error with logger.error
 * @param  {Error} err
 */
exports.log = function(err) {
    /* global logger */
    var parsedError = exports.parse(err);
    logger.error(parsedError.toString());
};<|endoftext|>


<commit_before>const deprecate = require('electron').deprecate;
const session = require('electron').session;
const Menu = require('electron').Menu;
const EventEmitter = require('events').EventEmitter;

const bindings = process.atomBinding('app');
const downloadItemBindings = process.atomBinding('download_item');
const app = bindings.app;

var slice = [].slice;

var appPath;
var fn;
var i;
var len;
var name;
var ref1;
var wrapDownloadItem;

app.__proto__ = EventEmitter.prototype;

app.setApplicationMenu = function(menu) {
  return Menu.setApplicationMenu(menu);
};

app.getApplicationMenu = function() {
  return Menu.getApplicationMenu();
};

app.commandLine = {
  appendSwitch: bindings.appendSwitch,
  appendArgument: bindings.appendArgument
};

if (process.platform === 'darwin') {
  app.dock = {
    bounce: function(type) {
      if (type == null) {
        type = 'informational';
      }
      return bindings.dockBounce(type);
    },
    cancelBounce: bindings.dockCancelBounce,
    setBadge: bindings.dockSetBadgeText,
    getBadge: bindings.dockGetBadgeText,
    hide: bindings.dockHide,
    show: bindings.dockShow,
    setMenu: bindings.dockSetMenu
  };
}

appPath = null;

app.setAppPath = function(path) {
  return appPath = path;
};

app.getAppPath = function() {
  return appPath;
};

// Routes the events to webContents.
ref1 = ['login', 'certificate-error', 'select-client-certificate'];
fn = function(name) {
  return app.on(name, function() {
    var args, event, webContents;
    event = arguments[0], webContents = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
    return webContents.emit.apply(webContents, [name, event].concat(slice.call(args)));
  });
};
for (i = 0, len = ref1.length; i < len; i++) {
  name = ref1[i];
  fn(name);
}

// Deprecated.

app.getHomeDir = deprecate('app.getHomeDir', 'app.getPath', function() {
  return this.getPath('home');
});

app.getDataPath = deprecate('app.getDataPath', 'app.getPath', function() {
  return this.getPath('userData');
});

app.setDataPath = deprecate('app.setDataPath', 'app.setPath', function(path) {
  return this.setPath('userData', path);
});

app.resolveProxy = deprecate('app.resolveProxy', 'session.defaultSession.resolveProxy', function(url, callback) {
  return session.defaultSession.resolveProxy(url, callback);
});

deprecate.rename(app, 'terminate', 'quit');

deprecate.event(app, 'finish-launching', 'ready', function() {

  // give default app a chance to setup default menu.
  return setImmediate((function(_this) {
    return function() {
      return _this.emit('finish-launching');
    };
  })(this));
});

deprecate.event(app, 'activate-with-no-open-windows', 'activate', function(event, hasVisibleWindows) {
  if (!hasVisibleWindows) {
    return this.emit('activate-with-no-open-windows', event);
  }
});

deprecate.event(app, 'select-certificate', 'select-client-certificate');

// Wrappers for native classes.
wrapDownloadItem = function(downloadItem) {

  // downloadItem is an EventEmitter.
  downloadItem.__proto__ = EventEmitter.prototype;

  // Deprecated.
  deprecate.property(downloadItem, 'url', 'getURL');
  deprecate.property(downloadItem, 'filename', 'getFilename');
  deprecate.property(downloadItem, 'mimeType', 'getMimeType');
  return deprecate.rename(downloadItem, 'getUrl', 'getURL');
};

downloadItemBindings._setWrapDownloadItem(wrapDownloadItem);

// Only one App object pemitted.
module.exports = app;
<commit_msg>Inline `var`<commit_after>const deprecate = require('electron').deprecate;
const session = require('electron').session;
const Menu = require('electron').Menu;
const EventEmitter = require('events').EventEmitter;

const bindings = process.atomBinding('app');
const downloadItemBindings = process.atomBinding('download_item');
const app = bindings.app;

var slice = [].slice;

app.__proto__ = EventEmitter.prototype;

app.setApplicationMenu = function(menu) {
  return Menu.setApplicationMenu(menu);
};

app.getApplicationMenu = function() {
  return Menu.getApplicationMenu();
};

app.commandLine = {
  appendSwitch: bindings.appendSwitch,
  appendArgument: bindings.appendArgument
};

if (process.platform === 'darwin') {
  app.dock = {
    bounce: function(type) {
      if (type == null) {
        type = 'informational';
      }
      return bindings.dockBounce(type);
    },
    cancelBounce: bindings.dockCancelBounce,
    setBadge: bindings.dockSetBadgeText,
    getBadge: bindings.dockGetBadgeText,
    hide: bindings.dockHide,
    show: bindings.dockShow,
    setMenu: bindings.dockSetMenu
  };
}

var appPath = null;

app.setAppPath = function(path) {
  return appPath = path;
};

app.getAppPath = function() {
  return appPath;
};

// Routes the events to webContents.
var ref1 = ['login', 'certificate-error', 'select-client-certificate'];
var fn = function(name) {
  return app.on(name, function() {
    var args, event, webContents;
    event = arguments[0], webContents = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
    return webContents.emit.apply(webContents, [name, event].concat(slice.call(args)));
  });
};
var i, len;
for (i = 0, len = ref1.length; i < len; i++) {
  var name = ref1[i];
  fn(name);
}

// Deprecated.

app.getHomeDir = deprecate('app.getHomeDir', 'app.getPath', function() {
  return this.getPath('home');
});

app.getDataPath = deprecate('app.getDataPath', 'app.getPath', function() {
  return this.getPath('userData');
});

app.setDataPath = deprecate('app.setDataPath', 'app.setPath', function(path) {
  return this.setPath('userData', path);
});

app.resolveProxy = deprecate('app.resolveProxy', 'session.defaultSession.resolveProxy', function(url, callback) {
  return session.defaultSession.resolveProxy(url, callback);
});

deprecate.rename(app, 'terminate', 'quit');

deprecate.event(app, 'finish-launching', 'ready', function() {

  // give default app a chance to setup default menu.
  return setImmediate((function(_this) {
    return function() {
      return _this.emit('finish-launching');
    };
  })(this));
});

deprecate.event(app, 'activate-with-no-open-windows', 'activate', function(event, hasVisibleWindows) {
  if (!hasVisibleWindows) {
    return this.emit('activate-with-no-open-windows', event);
  }
});

deprecate.event(app, 'select-certificate', 'select-client-certificate');

// Wrappers for native classes.
var wrapDownloadItem = function(downloadItem) {

  // downloadItem is an EventEmitter.
  downloadItem.__proto__ = EventEmitter.prototype;

  // Deprecated.
  deprecate.property(downloadItem, 'url', 'getURL');
  deprecate.property(downloadItem, 'filename', 'getFilename');
  deprecate.property(downloadItem, 'mimeType', 'getMimeType');
  return deprecate.rename(downloadItem, 'getUrl', 'getURL');
};

downloadItemBindings._setWrapDownloadItem(wrapDownloadItem);

// Only one App object pemitted.
module.exports = app;
<|endoftext|>


<commit_before>/**
* Creates an instance of Error that aggregates and preserves an innerError.
* @param message The error message.
* @param innerError The inner error message to aggregate.
* @param skipIfAlreadyAggregate Indicates to not wrap the inner error if it itself already has an innerError.
* @return The Error instance.
*/
export function AggregateError(message: string, innerError?: Error, skipIfAlreadyAggregate?: boolean): Error {
  if (innerError) {
    if (innerError.innerError && skipIfAlreadyAggregate) {
      return innerError;
    }

    const separator = '\n------------------------------------------------\n';

    message += `${separator}Inner Error:\n`;

    if (typeof (innerError) === 'string') {
      message += `Message: ${innerError}`;
    } else {
      if (innerError.message) {
        message += `Message: ${innerError.message}`;
      } else {
        message += `Unknown Inner Error Type. Displaying Inner Error as JSON:\n ${JSON.stringify(innerError, null, '  ')}`;
      }

      if (innerError.stack) {
        message += `\nInner Error Stack:\n${innerError.stack}`;
        message += '\nEnd Inner Error Stack';
      }
    }

    message += separator;
  }

  let e = new Error(message);
  if (innerError) {
    e.innerError = innerError;
  }

  return e;
}

/**
* Enables discovery of what features the runtime environment supports.
*/
interface Feature {
  /**
  * Does the runtime environment support ShadowDOM?
  */
  shadowDOM: boolean;
  /**
  * Does the runtime environment support the css scoped attribute?
  */
  scopedCSS: boolean;
  /**
  * Does the runtime environment support native HTMLTemplateElement?
  */
  htmlTemplateElement: boolean;

  /**
  * Does the runtime environment support native DOM mutation observers?
  */
  mutationObserver: boolean;
}

/**
* The singleton instance of the Feature discovery API.
*/
export const FEATURE: Feature = {};

/**
* The runtime's performance API.
*/
interface Performance {
  /**
  * Gets a DOMHighResTimeStamp.
  * @return The timestamp, measured in milliseconds, accurate to one thousandth of a millisecond.
  */
  now(): number;

  /**
   * Removes the given mark from the browser's performance entry buffer.
   *
   * @param {string} [markName] A DOMString representing the name of the timestamp. If this argument is omitted, all performance entries with an entry type of "mark" will be removed.
   * @memberof IPerformance
   */
  clearMarks(markName?: string): void;

  /**
   * Removes the given measure from the browser's performance entry buffer.
   *
   * @param {string} [measureName] A DOMString representing the name of the timestamp. If this argument is omitted, all performance entries with an entry type of "measure" will be removed.
   * @memberof IPerformance
   */
  clearMeasures(measureName?: string): void;

  /**
   * Returns a list of PerformanceEntry objects based on the given name and entry type.
   *
   * @param {string} name The name of the entry to retrieve
   * @param {string} [entryType] The type of entry to retrieve such as "mark". The valid entry types are listed in PerformanceEntry.entryType.
   * @returns {*}
   * @memberof IPerformance
   */
  getEntriesByName(name: string, entryType?: string): any;

  /**
   * Returns a list of PerformanceEntry objects of the given entry type.
   *
   * @param {string} entryType The type of entry to retrieve such as "mark". The valid entry types are listed in PerformanceEntry.entryType.
   * @returns {*}
   * @memberof IPerformance
   */
  getEntriesByType(entryType: string): any;

  /**
   * Creates a timestamp in the browser's performance entry buffer with the given name.
   *
   * @param {string} markName a DOMString representing the name of the mark
   * @memberof IPerformance
   */
  mark(markName: string): void;

  /**
   * Creates a named timestamp in the browser's performance entry buffer between two specified marks (known as the start mark and end mark, respectively).
   *
   * @param {string} measureName a DOMString representing the name of the measure.
   * @param {string} [startMarkName] A DOMString representing the name of the measure's starting mark. May also be the name of a PerformanceTiming property.
   * @param {string} [endMarkName] A DOMString representing the name of the measure's ending mark. May also be the name of a PerformanceTiming property.
   * @memberof IPerformance
   */
  measure(measureName: string, startMarkName?: string, endMarkName?: string): void;
}

/**
* Represents the core APIs of the runtime environment.
*/
interface Platform {
  /**
  * The runtime environment's global.
  */
  global: any,
  /**
  * A function wich does nothing.
  */
  noop: Function;
  /**
  * The runtime's location API.
  */
  location: typeof window.location;
  /**
  * The runtime's history API.
  */
  history: typeof window.history;
  /**
  * The runtime's performance API
  */
  performance: Performance;
  /**
  * Registers a function to call when the system is ready to update (repaint) the display.
  * @param callback The function to call.
  * @return A long integer value, the request id, that uniquely identifies the entry in the callback list.
  */
  requestAnimationFrame(callback: (animationFrameStart: number) => void): number;
  /**
  * The runtime's XMLHttpRequest API.
  */
  XMLHttpRequest: typeof XMLHttpRequest;
  /**
  * Iterate all modules loaded by the script loader.
  * @param callback A callback that will receive each module id along with the module object. Return true to end enumeration.
  */
  eachModule(callback: (key: string, value: Object) => boolean): void;
  /**
  * Add a global event listener.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function that receives a notification when an event of the specified type occurs.
  * @param capture If true, useCapture indicates that the user wishes to initiate capture.
  */
  addEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture?: boolean): void;
  /**
  * Remove a global event listener.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function to remove from the event.
  * @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
  */
  removeEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture?: boolean): void;
  /**
   * Reference to the Loader Class (set after the loader has been first imported)
   */
  Loader: any;
  /**
   * Resolves a module name to a path resolvable by the loader. By default returns the first parameter.
   * It is recommended to use this for all dynamic imports as it enables static analysis
   * and optionally allows adding custom metadata used by the build step.
   *
   * References to this method should always literally call `PLATFORM.moduleName(...)`.
   * This enables the build step to statically optimize the code by replacing the reference with a string.
   *
   * @param moduleName Absolute or relative path to the module.
   * @param options Optional options used during the static analysis that inform how to process the module.
   */
  moduleName(moduleName: string, options?: ModuleNameOptions): string;
  moduleName(moduleName: string, chunk?: string): string;
}

/**
 * Options used during the static analysis that inform how to process a given module.
 */
interface ModuleNameOptions {
  /**
   * Add the module to a chunk by name
   */
  chunk?: string;
  /**
   * Optionally declare which exports are used. This enables tree-shaking when only few out of many exports are used.
   */
  exports?: string[];
}

/**
* The singleton instance of the Platform API.
*/
export const PLATFORM: Platform = {
  noop() { },
  eachModule() { },
  moduleName(moduleName) {
    return moduleName;
  }
};

PLATFORM.global = (function() {
  // Workers don’t have `window`, only `self`
  if (typeof self !== 'undefined') {
    return self;
  }

  if (typeof global !== 'undefined') {
    return global;
  }

  // Not all environments allow eval and Function
  // Use only as a last resort:
  return new Function('return this')();
})();

/**
* Represents the core APIs of the DOM.
*/
interface Dom {
  /**
  * The global DOM Element type.
  */
  Element: typeof Element;
  /**
  * The global DOM NodeList type.
  */
  NodeList: typeof NodeList;
  /**
  * The global DOM SVGElement type.
  */
  SVGElement: typeof SVGElement;
  /**
  * A key representing a DOM boundary.
  */
  boundary: string;
  /**
  * The document title.
  */
  title: string;
  /**
  * The document's active/focused element.
  */
  activeElement: Element;
  /**
  * Add an event listener to the document.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function or listener object that receives a notification when an event of the specified type occurs.
  * @param capture If true, useCapture indicates that the user wishes to initiate capture.
  */
  addEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture: boolean): void;
  /**
  * Remove an event listener from the document.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function or listener object to remove from the event.
  * @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
  */
  removeEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture: boolean): void;
  /**
  * Adopts a node from an external document.
  * @param node The node to be adopted.
  * @return The adopted node able to be used in the document.
  */
  adoptNode(node: Node): Node;
  /**
  * Creates the specified HTML element or an HTMLUnknownElement if the given element name isn't a known one.
  * @param tagName A string that specifies the type of element to be created.
  * @return The created element.
  */
  createElement<T extends HTMLElementTagNameMap>(tagName: T): HTMLElementTagNameMap<T>;
  createElement(tagName: string): HTMLElement;
  /**
  * Creates the specified HTML attribute
  * @param name A string that specifies the name of attribute to be created.
  * @return The created attribute.
  */
  createAttribute(name: string): Attr;
  /**
  * Creates a new Text node.
  * @param text A string to populate the new Text node.
  * @return A Text node.
  */
  createTextNode(text: string): Text;
  /**
  * Creates a new Comment node.
  * @param text A string to populate the new Comment node.
  * @return A Comment node.
  */
  createComment(text: string): Comment;
  /**
  * Creates a new DocumentFragment.
  * @return A DocumentFragment.
  */
  createDocumentFragment(): DocumentFragment;
  /**
  * Creates a new HTMLTemplateElement.
  * @return An HTMLTemplateElement.
  */
  createTemplateElement(): HTMLTemplateElement;
  /**
  * Creates a new MutationObserver.
  * @param callback A callback that will recieve the change records with the mutations.
  * @return A MutationObservere.
  */
  createMutationObserver(callback: Function): MutationObserver;
  /**
  * Creates a new CustomEvent.
  * @param eventType A string representing the event type.
  * @param options An options object specifying bubbles:boolean, cancelable:boolean and/or detail:Object information.
  * @return A CustomEvent.
  */
  createCustomEvent<T = any>(eventType: string, options?: CustomEventInit<T>): CustomEvent<T>;
  /**
  * Dispatches an event on the document.
  * @param evt The event to dispatch.
  */
  dispatchEvent(evt: Event): void;
  /**
  * Gives the values of all the CSS properties of an element after applying the active stylesheets and resolving any basic computation those values may contain.
  * @param element The Element for which to get the computed style.
  * @return The computed styles.
  */
  getComputedStyle(element: Element): CSSStyleDeclaration;
  /**
  * Locates an element in the document according to its id.
  * @param id The id to search the document for.
  * @return The found element.
  */
  getElementById(id: string): Element;
  /**
  * Performs a query selector on the document and returns first matched element, depth first.
  * @param query The query to use in searching the document.
  * @return A list of all matched elements in the document.
  */
  querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
  querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
  querySelector<E extends Element = Element>(selectors: string): E | null;
  /**
  * Performs a query selector on the document and returns all located matches.
  * @param query The query to use in searching the document.
  * @return A list of all matched elements in the document.
  */
  querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
  querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
  querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
  /**
  * Gets the element that is the next sibling of the provided element.
  * @param element The element whose next sibling is being located.
  * @return The next sibling Element of the provided Element.
  */
  nextElementSibling(element: Node): Element;
  /**
  * Creates an HTMLTemplateElement using the markup provided.
  * @param markup A string containing the markup to turn into a template. Note: This string must contain the template element as well.
  * @return The instance of HTMLTemplateElement that was created from the provided markup.
  */
  createTemplateFromMarkup(markup: string): HTMLTemplateElement;
  /**
  * Appends a node to the parent, if provided, or the document.body otherwise.
  * @param newNode The node to append.
  * @param parentNode The node to append to, otherwise the document.body.
  */
  appendNode(newNode: Node, parentNode?: Node): void;
  /**
  * Replaces a node in the parent with a new node.
  * @param newNode The node to replace the old node with.
  * @param node The node that is being replaced.
  * @param parentNode The node that the current node is parented to.
  */
  replaceNode(newNode: Node, node: Node, parentNode?: Node): void;
  /**
  * Removes the specified node from the parent node.
  * @param node The node to remove.
  * @param parentNode The parent node from which the node will be removed.
  */
  removeNode(node: Node, parentNode?: Node): void;
  /**
  * Injects styles into the destination element, or the document.head if no destination is provided.
  * @param styles The css text to injext.
  * @param destination The destination element to inject the css text into. If not specified it will default to the document.head.
  * @param prepend Indicates whether or not the styles should be prepended to the destination. By default they are appended.
  * @param id The existing style element's id to replace the contents for
  * @return The Style node that was created.
  */
  injectStyles(styles: string, destination?: Element, prepend?: boolean, id?: string): Node;
}

/**
* The singleton instance of the Dom API.
*/
export const DOM: Dom = {};
export let isInitialized = false;
/**
* Enables initializing a specific implementation of the Platform Abstraction Layer (PAL).
* @param callback Allows providing a callback which configures the three PAL singletons with their platform-specific implementations.
*/
export function initializePAL(callback: (platform: Platform, feature: Feature, dom: Dom) => void): void {
  if (isInitialized) {
    return;
  }
  isInitialized = true;
  if (typeof Object.getPropertyDescriptor !== 'function') {
    Object.getPropertyDescriptor = function(subject, name) {
      let pd = Object.getOwnPropertyDescriptor(subject, name);
      let proto = Object.getPrototypeOf(subject);
      while (typeof pd === 'undefined' && proto !== null) {
        pd = Object.getOwnPropertyDescriptor(proto, name);
        proto = Object.getPrototypeOf(proto);
      }
      return pd;
    };
  }

  callback(PLATFORM, FEATURE, DOM);
}
export function reset() {
  isInitialized = false;
}
<commit_msg>fix(lint): fix lint issues<commit_after>/**
* Creates an instance of Error that aggregates and preserves an innerError.
* @param message The error message.
* @param innerError The inner error message to aggregate.
* @param skipIfAlreadyAggregate Indicates to not wrap the inner error if it itself already has an innerError.
* @return The Error instance.
*/
export function AggregateError(message: string, innerError?: Error, skipIfAlreadyAggregate?: boolean): Error {
  if (innerError) {
    if (innerError.innerError && skipIfAlreadyAggregate) {
      return innerError;
    }

    const separator = '\n------------------------------------------------\n';

    message += `${separator}Inner Error:\n`;

    if (typeof (innerError) === 'string') {
      message += `Message: ${innerError}`;
    } else {
      if (innerError.message) {
        message += `Message: ${innerError.message}`;
      } else {
        message += `Unknown Inner Error Type. Displaying Inner Error as JSON:\n ${JSON.stringify(innerError, null, '  ')}`;
      }

      if (innerError.stack) {
        message += `\nInner Error Stack:\n${innerError.stack}`;
        message += '\nEnd Inner Error Stack';
      }
    }

    message += separator;
  }

  let e = new Error(message);
  if (innerError) {
    e.innerError = innerError;
  }

  return e;
}

/**
* Enables discovery of what features the runtime environment supports.
*/
interface Feature {
  /**
  * Does the runtime environment support ShadowDOM?
  */
  shadowDOM: boolean;
  /**
  * Does the runtime environment support the css scoped attribute?
  */
  scopedCSS: boolean;
  /**
  * Does the runtime environment support native HTMLTemplateElement?
  */
  htmlTemplateElement: boolean;

  /**
  * Does the runtime environment support native DOM mutation observers?
  */
  mutationObserver: boolean;
}

/**
* The singleton instance of the Feature discovery API.
*/
export const FEATURE: Feature = {};

/**
* The runtime's performance API.
*/
interface Performance {
  /**
  * Gets a DOMHighResTimeStamp.
  * @return The timestamp, measured in milliseconds, accurate to one thousandth of a millisecond.
  */
  now(): number;

  /**
   * Removes the given mark from the browser's performance entry buffer.
   *
   * @param {string} [markName] A DOMString representing the name of the timestamp. If this argument is omitted, all performance entries with an entry type of "mark" will be removed.
   * @memberof IPerformance
   */
  clearMarks(markName?: string): void;

  /**
   * Removes the given measure from the browser's performance entry buffer.
   *
   * @param {string} [measureName] A DOMString representing the name of the timestamp. If this argument is omitted, all performance entries with an entry type of "measure" will be removed.
   * @memberof IPerformance
   */
  clearMeasures(measureName?: string): void;

  /**
   * Returns a list of PerformanceEntry objects based on the given name and entry type.
   *
   * @param {string} name The name of the entry to retrieve
   * @param {string} [entryType] The type of entry to retrieve such as "mark". The valid entry types are listed in PerformanceEntry.entryType.
   * @returns {*}
   * @memberof IPerformance
   */
  getEntriesByName(name: string, entryType?: string): any;

  /**
   * Returns a list of PerformanceEntry objects of the given entry type.
   *
   * @param {string} entryType The type of entry to retrieve such as "mark". The valid entry types are listed in PerformanceEntry.entryType.
   * @returns {*}
   * @memberof IPerformance
   */
  getEntriesByType(entryType: string): any;

  /**
   * Creates a timestamp in the browser's performance entry buffer with the given name.
   *
   * @param {string} markName a DOMString representing the name of the mark
   * @memberof IPerformance
   */
  mark(markName: string): void;

  /**
   * Creates a named timestamp in the browser's performance entry buffer between two specified marks (known as the start mark and end mark, respectively).
   *
   * @param {string} measureName a DOMString representing the name of the measure.
   * @param {string} [startMarkName] A DOMString representing the name of the measure's starting mark. May also be the name of a PerformanceTiming property.
   * @param {string} [endMarkName] A DOMString representing the name of the measure's ending mark. May also be the name of a PerformanceTiming property.
   * @memberof IPerformance
   */
  measure(measureName: string, startMarkName?: string, endMarkName?: string): void;
}

/**
* Represents the core APIs of the runtime environment.
*/
interface Platform {
  /**
  * The runtime environment's global.
  */
  global: any;
  /**
  * A function wich does nothing.
  */
  noop: Function;
  /**
  * The runtime's location API.
  */
  location: typeof window.location;
  /**
  * The runtime's history API.
  */
  history: typeof window.history;
  /**
  * The runtime's performance API
  */
  performance: Performance;
  /**
  * Registers a function to call when the system is ready to update (repaint) the display.
  * @param callback The function to call.
  * @return A long integer value, the request id, that uniquely identifies the entry in the callback list.
  */
  requestAnimationFrame(callback: (animationFrameStart: number) => void): number;
  /**
  * The runtime's XMLHttpRequest API.
  */
  XMLHttpRequest: typeof XMLHttpRequest;
  /**
  * Iterate all modules loaded by the script loader.
  * @param callback A callback that will receive each module id along with the module object. Return true to end enumeration.
  */
  eachModule(callback: (key: string, value: Object) => boolean): void;
  /**
  * Add a global event listener.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function that receives a notification when an event of the specified type occurs.
  * @param capture If true, useCapture indicates that the user wishes to initiate capture.
  */
  addEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture?: boolean): void;
  /**
  * Remove a global event listener.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function to remove from the event.
  * @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
  */
  removeEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture?: boolean): void;
  /**
   * Reference to the Loader Class (set after the loader has been first imported)
   */
  Loader: any;
  /**
   * Resolves a module name to a path resolvable by the loader. By default returns the first parameter.
   * It is recommended to use this for all dynamic imports as it enables static analysis
   * and optionally allows adding custom metadata used by the build step.
   *
   * References to this method should always literally call `PLATFORM.moduleName(...)`.
   * This enables the build step to statically optimize the code by replacing the reference with a string.
   *
   * @param moduleName Absolute or relative path to the module.
   * @param options Optional options used during the static analysis that inform how to process the module.
   */
  moduleName(moduleName: string, options?: ModuleNameOptions): string;
  moduleName(moduleName: string, chunk?: string): string;
}

/**
 * Options used during the static analysis that inform how to process a given module.
 */
interface ModuleNameOptions {
  /**
   * Add the module to a chunk by name
   */
  chunk?: string;
  /**
   * Optionally declare which exports are used. This enables tree-shaking when only few out of many exports are used.
   */
  exports?: string[];
}

/**
* The singleton instance of the Platform API.
*/
export const PLATFORM: Platform = {
  noop() { },
  eachModule() { },
  moduleName(moduleName) {
    return moduleName;
  }
};

PLATFORM.global = (function() {
  // Workers don’t have `window`, only `self`
  if (typeof self !== 'undefined') {
    return self;
  }

  if (typeof global !== 'undefined') {
    return global;
  }

  // Not all environments allow eval and Function
  // Use only as a last resort:
  return new Function('return this')();
})();

/**
* Represents the core APIs of the DOM.
*/
interface Dom {
  /**
  * The global DOM Element type.
  */
  Element: typeof Element;
  /**
  * The global DOM NodeList type.
  */
  NodeList: typeof NodeList;
  /**
  * The global DOM SVGElement type.
  */
  SVGElement: typeof SVGElement;
  /**
  * A key representing a DOM boundary.
  */
  boundary: string;
  /**
  * The document title.
  */
  title: string;
  /**
  * The document's active/focused element.
  */
  activeElement: Element;
  /**
  * Add an event listener to the document.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function or listener object that receives a notification when an event of the specified type occurs.
  * @param capture If true, useCapture indicates that the user wishes to initiate capture.
  */
  addEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture: boolean): void;
  /**
  * Remove an event listener from the document.
  * @param eventName A string representing the event type to listen for.
  * @param callback The function or listener object to remove from the event.
  * @param capture Specifies whether the listener to be removed was registered as a capturing listener or not.
  */
  removeEventListener(eventName: string, callback: EventListenerOrEventListenerObject, capture: boolean): void;
  /**
  * Adopts a node from an external document.
  * @param node The node to be adopted.
  * @return The adopted node able to be used in the document.
  */
  adoptNode(node: Node): Node;
  /**
  * Creates the specified HTML element or an HTMLUnknownElement if the given element name isn't a known one.
  * @param tagName A string that specifies the type of element to be created.
  * @return The created element.
  */
  // createElement<T extends keyof HTMLElementTagNameMap>(tagName: T): HTMLElementTagNameMap<T>;
  createElement(tagName: string): HTMLElement;
  /**
  * Creates the specified HTML attribute
  * @param name A string that specifies the name of attribute to be created.
  * @return The created attribute.
  */
  createAttribute(name: string): Attr;
  /**
  * Creates a new Text node.
  * @param text A string to populate the new Text node.
  * @return A Text node.
  */
  createTextNode(text: string): Text;
  /**
  * Creates a new Comment node.
  * @param text A string to populate the new Comment node.
  * @return A Comment node.
  */
  createComment(text: string): Comment;
  /**
  * Creates a new DocumentFragment.
  * @return A DocumentFragment.
  */
  createDocumentFragment(): DocumentFragment;
  /**
  * Creates a new HTMLTemplateElement.
  * @return An HTMLTemplateElement.
  */
  createTemplateElement(): HTMLTemplateElement;
  /**
  * Creates a new MutationObserver.
  * @param callback A callback that will recieve the change records with the mutations.
  * @return A MutationObservere.
  */
  createMutationObserver(callback: Function): MutationObserver;
  /**
  * Creates a new CustomEvent.
  * @param eventType A string representing the event type.
  * @param options An options object specifying bubbles:boolean, cancelable:boolean and/or detail:Object information.
  * @return A CustomEvent.
  */
  createCustomEvent(eventType: string, options?: CustomEventInit): CustomEvent;
  /**
  * Dispatches an event on the document.
  * @param evt The event to dispatch.
  */
  dispatchEvent(evt: Event): void;
  /**
  * Gives the values of all the CSS properties of an element after applying the active stylesheets and resolving any basic computation those values may contain.
  * @param element The Element for which to get the computed style.
  * @return The computed styles.
  */
  getComputedStyle(element: Element): CSSStyleDeclaration;
  /**
  * Locates an element in the document according to its id.
  * @param id The id to search the document for.
  * @return The found element.
  */
  getElementById(id: string): Element;
  /**
  * Performs a query selector on the document and returns first matched element, depth first.
  * @param query The query to use in searching the document.
  * @return A list of all matched elements in the document.
  */
  // enable the following two lines if we switch to TypeScript
  // querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
  // querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;
  querySelector(selectors: string): Element;
  /**
  * Performs a query selector on the document and returns all located matches.
  * @param query The query to use in searching the document.
  * @return A list of all matched elements in the document.
  */
  // enable the following two lines if we switch to TypeScript
  // querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
  // querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;
  querySelectorAll(selectors: string): NodeList;
  /**
  * Gets the element that is the next sibling of the provided element.
  * @param element The element whose next sibling is being located.
  * @return The next sibling Element of the provided Element.
  */
  nextElementSibling(element: Node): Element;
  /**
  * Creates an HTMLTemplateElement using the markup provided.
  * @param markup A string containing the markup to turn into a template. Note: This string must contain the template element as well.
  * @return The instance of HTMLTemplateElement that was created from the provided markup.
  */
  createTemplateFromMarkup(markup: string): HTMLTemplateElement;
  /**
  * Appends a node to the parent, if provided, or the document.body otherwise.
  * @param newNode The node to append.
  * @param parentNode The node to append to, otherwise the document.body.
  */
  appendNode(newNode: Node, parentNode?: Node): void;
  /**
  * Replaces a node in the parent with a new node.
  * @param newNode The node to replace the old node with.
  * @param node The node that is being replaced.
  * @param parentNode The node that the current node is parented to.
  */
  replaceNode(newNode: Node, node: Node, parentNode?: Node): void;
  /**
  * Removes the specified node from the parent node.
  * @param node The node to remove.
  * @param parentNode The parent node from which the node will be removed.
  */
  removeNode(node: Node, parentNode?: Node): void;
  /**
  * Injects styles into the destination element, or the document.head if no destination is provided.
  * @param styles The css text to injext.
  * @param destination The destination element to inject the css text into. If not specified it will default to the document.head.
  * @param prepend Indicates whether or not the styles should be prepended to the destination. By default they are appended.
  * @param id The existing style element's id to replace the contents for
  * @return The Style node that was created.
  */
  injectStyles(styles: string, destination?: Element, prepend?: boolean, id?: string): Node;
}

/**
* The singleton instance of the Dom API.
*/
export const DOM: Dom = {};
export let isInitialized = false;
/**
* Enables initializing a specific implementation of the Platform Abstraction Layer (PAL).
* @param callback Allows providing a callback which configures the three PAL singletons with their platform-specific implementations.
*/
export function initializePAL(callback: (platform: Platform, feature: Feature, dom: Dom) => void): void {
  if (isInitialized) {
    return;
  }
  isInitialized = true;
  if (typeof Object.getPropertyDescriptor !== 'function') {
    Object.getPropertyDescriptor = function(subject, name) {
      let pd = Object.getOwnPropertyDescriptor(subject, name);
      let proto = Object.getPrototypeOf(subject);
      while (typeof pd === 'undefined' && proto !== null) {
        pd = Object.getOwnPropertyDescriptor(proto, name);
        proto = Object.getPrototypeOf(proto);
      }
      return pd;
    };
  }

  callback(PLATFORM, FEATURE, DOM);
}
export function reset() {
  isInitialized = false;
}
<|endoftext|>