<commit_before>
//Modules
	var async       = require('async');
	var tools       = require('./tools.js');
	var fs          = require('fs');
	var pathMod     = require('path');
	var Handlebars  = require('handlebars');
	var vCard       = require('vcards-js');
	var vcardparser = require('vcardparser');
	var _ 		      = require('lodash');
	_.mixin( require('lodash-deep') );

//Global Variables
	var templates = {};

//Private functions
	(function loadTemplates(){

		var files = fs.readdirSync(__dirname + '/templates');

		files.forEach(function(templateDir){
			templates[templateDir] = fs.readFileSync(__dirname + '/templates/' + templateDir, {encoding : 'utf8'});
			templates[templateDir] = Handlebars.compile(templates[templateDir]);
		});

	})();

//Public functions

	var Sync = function( config ){
		this.config = config;
		this.protocol
	};

	Sync.prototype.createAddressbook = function( path, info, callback ){

		if(!path){
			return callback({err : "Error: path required"});
		}

		var body = templates['newAddressbook'](info);
		path = path + tools.uuid() + '/';

		this.request('MKCOL', path, body, function (err, res) {

			if (err || res.statusCode !== 201) {
				callback({err : err, statusCode : res.statusCode});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.modifyAddressbook = function( path, info, callback ){

		if(!path){
			return callback({err : "Error: path required"});
		}

		var body = templates['modifyAddressbook'](info);

		this.request('PROPPATCH', path, body, function (err, res) {

			if (err) {
				callback({err : err});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.createContact = function ( path, info, callback ) {

		var body = tools.jsonToVCard( info );
		path = pathMod.join( path, tools.uuid() + '.vcf' );

		this.request( 'PUT', {
			path : path,
			headers : {
				'If-None-Match' : '*',
				'Content-Type': 'text/vcard; charset=utf-8'
			}}, body, function (err, res) {

			if (err || res.statusCode !== 201) {
				callback({err : err, statusCode : res.statusCode});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.deleteAddressbook = function ( path, callback ) {

		this.request('DELETE', path, '', function (err, res) {
			callback(err);
		});

	};

	Sync.prototype.deleteContact = function ( path, callback ) {

		this.request('DELETE', path, '', function (err, res) {
			callback(err);
		});

	};

	Sync.prototype.getAddressbooks = function( calHome, callback ){

		var body = templates['getAddressbooks']();

		this.request( 'PROPFIND', { path : calHome, depth : 1 }, body, function( error, res ){

			tools.parseXML( res.body, function ( err, data ){

				if( err ){
					return callback( err );
				}

				var addressbooks = _.map(data.response, function(internal){
					var newObj = {};
					newObj.href = internal.href;
					newObj = _.extend(newObj, _.deepGet(internal, 'propstat[0].prop[0]'));
					newObj = _.reduce(newObj, tools.normalizeAddressbookAttribute, {});
					return newObj;
				});

				addressbooks = _.filter(addressbooks, function(item){
					return item.resourcetype.indexOf('addressbook') !== -1;
				});

				callback(null, addressbooks);

			});

		});

	};

	Sync.prototype.getContact = function( path, callback ){

		this.request( 'GET', path, '', function( error, res ){

			if(error || res.statusCode !== 200){
				return callback('UNABLE TO RETRIEVE CONTACT');
			}

			vcardparser.parseString( res.body, function(err, json) {

				if(err) {
					return callback(err);
				}

				//newObj['address-data'] = tools.VCardToJson( json );
				callback( null, tools.VCardToJson( json ) );

			});

		});

	};

	Sync.prototype.login = function( callback ){

		this.request( 'OPTIONS', '', '', function( error, res ){

			if(error){
				callback(true);
			}
			else {
				callback(null, res.statusCode === 200);
			}

		});

	};

	Sync.prototype.getHome = function( callback ){

		this.request( 'PROPFIND', '', templates['getHome'](), function( error, res ){

			tools.parseXML( res.body, function( err, data ){

				if( err ){
					return callback( err );
				}

				callback(null, _.deepGet(data, 'response[0].propstat[0].prop[0].current-user-principal[0].href[0]'));

			});

		});

	};

	Sync.prototype.getAddressbookHome = function( home, callback ){

		this.request( 'PROPFIND', home, templates['getAddressbookHome'](), function( err, res ){

			tools.parseXML( res.body, function( err, data ){

				if( err ){
					return callback( err );
				}

				callback(null, _.deepGet(data, 'response[0].propstat[0].prop[0].addressbook-home-set[0].href[0]'));

			});

		});

	};

	Sync.prototype.getContacts = function ( filter, path, callback ) {

		filter = filter || {};

		var body = templates['getContacts'](filter);
		body = body.replace(/^\s*$[\n\r]{1,}/gm, '');

		this.request('REPORT', { path : path, depth : 1 }, body, function (err, res) {

			if (err) {
				callback(err);
				return;
			}

			tools.parseXML( res.body, function ( err, data ) {

				if (err) {
					return callback(err);
				}

				if(!data || !data.response){
					return callback(null, []);
				}

				async.map( data.response, function(internal, callback){

					var newObj = {};
					newObj.href = internal.href;

					newObj = _.extend(newObj, _.deepGet(internal, 'propstat[0].prop[0]'));
					newObj = _.reduce(newObj, tools.normalizeAddressbookAttribute, {});

					vcardparser.parseString(newObj['address-data'], function(err, json) {

						if(err) {
							return callback(err);
						}

						newObj['address-data'] = tools.VCardToJson( json );
						callback( null, newObj );

					});

				}, callback);

			});

		});

	};

	Sync.prototype.modifyContact = function ( path, info, callback ) {

		var that = this;

		that.request( 'GET', path, '', function( error, res ){

			if(error || res.statusCode !== 200){
				return callback('UNABLE TO RETRIEVE CONTACT');
			}

			var etag = res.headers.etag;
			var body = tools.jsonToVCard( info );

			that.request(

				'PUT',
				{
					path : path,
					headers : {
						'If-Match' : etag,
						'Content-Type': 'text/vcard; charset=utf-8'
					}
				},
				body,
				function (err, res) {

					if (err || res.statusCode !== 204) {
						return callback({err : err, statusCode : res.statusCode});
					}

					callback(null, path);

				}

			);

		});

	};

	Sync.prototype.request = function( type, path, body, callback ){

		var opts = {

			host    : this.config.host,
			path    : typeof path === 'string' ? path || '' : path.path || '',
			method  : type,
			data    : body,
			port    : this.config.port || 5232,
			headers : {

				'brief'           : 't',
				'accept-language' : 'es-es',
				//'accept-encoding' : 'gzip, deflate',
				'connection'      : 'keep-alive',
				'user-agent'      : 'Inevio CalDAV Client',
				'prefer'          : 'return=minimal',
				'Accept'          : '*/*',
				'Content-Type'    : 'text/xml',
				'Content-Length'  : body.length,
				'Depth'           : path.depth || 0,
				'Authorization'   : 'Basic ' + new Buffer( this.config.credentials.user + ':' + this.config.credentials.password ).toString('base64')

			}
		};

		if(path.headers){
			opts.headers = _.extend(opts.headers, path.headers);
		}

		var self = this;

		tools.request( opts, this.config.secure, function( err, res ){

			if( err ){
				return callback( err );
			}else if( res.statusCode === 302 ){
				self.request( type, res.headers.location, body, callback );
			}else{
				callback( null, res );
			}

		});

	};

	module.exports = Sync;
<commit_msg>Debug<commit_after>
//Modules
	var async       = require('async');
	var tools       = require('./tools.js');
	var fs          = require('fs');
	var pathMod     = require('path');
	var Handlebars  = require('handlebars');
	var vCard       = require('vcards-js');
	var vcardparser = require('vcardparser');
	var _ 		      = require('lodash');
	_.mixin( require('lodash-deep') );

//Global Variables
	var templates = {};

//Private functions
	(function loadTemplates(){

		var files = fs.readdirSync(__dirname + '/templates');

		files.forEach(function(templateDir){
			templates[templateDir] = fs.readFileSync(__dirname + '/templates/' + templateDir, {encoding : 'utf8'});
			templates[templateDir] = Handlebars.compile(templates[templateDir]);
		});

	})();

//Public functions

	var Sync = function( config ){
		this.config = config;
		this.protocol
	};

	Sync.prototype.createAddressbook = function( path, info, callback ){

		if(!path){
			return callback({err : "Error: path required"});
		}

		var body = templates['newAddressbook'](info);
		path = path + tools.uuid() + '/';

		this.request('MKCOL', path, body, function (err, res) {

			if (err || res.statusCode !== 201) {
				callback({err : err, statusCode : res.statusCode});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.modifyAddressbook = function( path, info, callback ){

		if(!path){
			return callback({err : "Error: path required"});
		}

		var body = templates['modifyAddressbook'](info);

		this.request('PROPPATCH', path, body, function (err, res) {

			if (err) {
				callback({err : err});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.createContact = function ( path, info, callback ) {

		var body = tools.jsonToVCard( info );
		path = pathMod.join( path, tools.uuid() + '.vcf' );

		this.request( 'PUT', {
			path : path,
			headers : {
				'If-None-Match' : '*',
				'Content-Type': 'text/vcard; charset=utf-8'
			}}, body, function (err, res) {

			if (err || res.statusCode !== 201) {
				callback({err : err, statusCode : res.statusCode});
				return;
			}

			callback(null, path);
		});
	};

	Sync.prototype.deleteAddressbook = function ( path, callback ) {

		this.request('DELETE', path, '', function (err, res) {
			callback(err);
		});

	};

	Sync.prototype.deleteContact = function ( path, callback ) {

		this.request('DELETE', path, '', function (err, res) {
			callback(err);
		});

	};

	Sync.prototype.getAddressbooks = function( calHome, callback ){

		var body = templates['getAddressbooks']();

		this.request( 'PROPFIND', { path : calHome, depth : 1 }, body, function( error, res ){

			console.log( error, res.body )

			tools.parseXML( res.body, function ( err, data ){

				if( err ){
					return callback( err );
				}

				var addressbooks = _.map(data.response, function(internal){
					var newObj = {};
					newObj.href = internal.href;
					newObj = _.extend(newObj, _.deepGet(internal, 'propstat[0].prop[0]'));
					newObj = _.reduce(newObj, tools.normalizeAddressbookAttribute, {});
					return newObj;
				});

				addressbooks = _.filter(addressbooks, function(item){
					return item.resourcetype.indexOf('addressbook') !== -1;
				});

				callback(null, addressbooks);

			});

		});

	};

	Sync.prototype.getContact = function( path, callback ){

		this.request( 'GET', path, '', function( error, res ){

			if(error || res.statusCode !== 200){
				return callback('UNABLE TO RETRIEVE CONTACT');
			}

			vcardparser.parseString( res.body, function(err, json) {

				if(err) {
					return callback(err);
				}

				//newObj['address-data'] = tools.VCardToJson( json );
				callback( null, tools.VCardToJson( json ) );

			});

		});

	};

	Sync.prototype.login = function( callback ){

		this.request( 'OPTIONS', '', '', function( error, res ){

			if(error){
				callback(true);
			}
			else {
				callback(null, res.statusCode === 200);
			}

		});

	};

	Sync.prototype.getHome = function( callback ){

		this.request( 'PROPFIND', '', templates['getHome'](), function( error, res ){

			tools.parseXML( res.body, function( err, data ){

				if( err ){
					return callback( err );
				}

				callback(null, _.deepGet(data, 'response[0].propstat[0].prop[0].current-user-principal[0].href[0]'));

			});

		});

	};

	Sync.prototype.getAddressbookHome = function( home, callback ){

		this.request( 'PROPFIND', home, templates['getAddressbookHome'](), function( err, res ){

			tools.parseXML( res.body, function( err, data ){

				if( err ){
					return callback( err );
				}

				callback(null, _.deepGet(data, 'response[0].propstat[0].prop[0].addressbook-home-set[0].href[0]'));

			});

		});

	};

	Sync.prototype.getContacts = function ( filter, path, callback ) {

		filter = filter || {};

		var body = templates['getContacts'](filter);
		body = body.replace(/^\s*$[\n\r]{1,}/gm, '');

		this.request('REPORT', { path : path, depth : 1 }, body, function (err, res) {

			if (err) {
				callback(err);
				return;
			}

			tools.parseXML( res.body, function ( err, data ) {

				if (err) {
					return callback(err);
				}

				if(!data || !data.response){
					return callback(null, []);
				}

				async.map( data.response, function(internal, callback){

					var newObj = {};
					newObj.href = internal.href;

					newObj = _.extend(newObj, _.deepGet(internal, 'propstat[0].prop[0]'));
					newObj = _.reduce(newObj, tools.normalizeAddressbookAttribute, {});

					vcardparser.parseString(newObj['address-data'], function(err, json) {

						if(err) {
							return callback(err);
						}

						newObj['address-data'] = tools.VCardToJson( json );
						callback( null, newObj );

					});

				}, callback);

			});

		});

	};

	Sync.prototype.modifyContact = function ( path, info, callback ) {

		var that = this;

		that.request( 'GET', path, '', function( error, res ){

			if(error || res.statusCode !== 200){
				return callback('UNABLE TO RETRIEVE CONTACT');
			}

			var etag = res.headers.etag;
			var body = tools.jsonToVCard( info );

			that.request(

				'PUT',
				{
					path : path,
					headers : {
						'If-Match' : etag,
						'Content-Type': 'text/vcard; charset=utf-8'
					}
				},
				body,
				function (err, res) {

					if (err || res.statusCode !== 204) {
						return callback({err : err, statusCode : res.statusCode});
					}

					callback(null, path);

				}

			);

		});

	};

	Sync.prototype.request = function( type, path, body, callback ){

		var opts = {

			host    : this.config.host,
			path    : typeof path === 'string' ? path || '' : path.path || '',
			method  : type,
			data    : body,
			port    : this.config.port || 5232,
			headers : {

				'brief'           : 't',
				'accept-language' : 'es-es',
				//'accept-encoding' : 'gzip, deflate',
				'connection'      : 'keep-alive',
				'user-agent'      : 'Inevio CalDAV Client',
				'prefer'          : 'return=minimal',
				'Accept'          : '*/*',
				'Content-Type'    : 'text/xml',
				'Content-Length'  : body.length,
				'Depth'           : path.depth || 0,
				'Authorization'   : 'Basic ' + new Buffer( this.config.credentials.user + ':' + this.config.credentials.password ).toString('base64')

			}
		};

		if(path.headers){
			opts.headers = _.extend(opts.headers, path.headers);
		}

		var self = this;

		tools.request( opts, this.config.secure, function( err, res ){

			if( err ){
				return callback( err );
			}else if( res.statusCode === 302 ){
				self.request( type, res.headers.location, body, callback );
			}else{
				callback( null, res );
			}

		});

	};

	module.exports = Sync;
<|endoftext|>


<commit_before>/* jshint browser: true */
(function() {
  "use strict";
  /**
   * Confirm this is a nav menu item.
   *
   * @returns {Boolean} True if a nav item.
   */
  function isNavItem(id) {
    return /^menu-(?:\w+?)$/.test(id);
  }

  /**
   * Hide the current menu.
   */
  function hideNavMenu() {
    var menuVisible = document.querySelector(".menu-context.visible");
    var menuActive = document.querySelector(".menu .active");

    // Hide the currently visible menu
    if (menuVisible) {
      menuVisible.classList.remove("visible");
    }

    // Un-highlight the current nav item
    if (menuActive) {
      menuActive.classList.remove("active");
    }
  }

  var menusAreVisible = false,
      Qbody = document.querySelector("body"),
      Qmenu = document.querySelector(".menu"),
      QtextArea = document.querySelector("textarea");

  Qmenu.addEventListener("mouseover", function(e) {
    // Make sure we are on a nav item
    if (isNavItem(e.target.id)) {
      hideNavMenu();

      // Only display the menus if we are allowed to
      if (menusAreVisible) {
        // Display the currently hovered-over menu
        var contextMenu = e.target.id.match(/^menu-(\w+?)$/)[1];
        document.querySelector(".menu-context." +  contextMenu).classList.add("visible");
        e.target.classList.add("active");
      }
    }
  });

  Qmenu.addEventListener("click", function(e) {
    // Close the menu if the label is clicked again
    if (isNavItem(e.target.id) && menusAreVisible) {
      menusAreVisible = false;
      hideNavMenu();
      return;
    }

    // Make sure the desired menu is not already visible
    if (isNavItem(e.target.id) && !e.target.classList.contains("visible")) {
      // Menus are allowed to be shown
      menusAreVisible = true;

      // Display the desired menu
      var contextMenu = e.target.id.match(/^menu-(\w+?)$/)[1];
      document.querySelector(".menu-context." +  contextMenu).classList.add("visible");
      e.target.classList.add("active");
    }
   });

  Qbody.addEventListener("click", function(e) {
    if (!isNavItem(e.target.id) && !e.target.classList.contains("menu-disabled") &&
        !e.target.classList.contains("blank")) {
      // Menus are not allowed to be shown at this time
      if (menusAreVisible) {
        menusAreVisible = false;
        hideNavMenu();
      }
    }
  });

  var Notepad = (function() {
    var self = null;

    /**
     * Get the class of the current theme.
     *
     * @private
     * @returns {String}
     */
    function __getCurrentTheme(body) {
      return body.className.match(/^win\d{1,2}$/)[0];
    }

    /**
     * Create a Notepad API instance.
     *
     * @constructs Notepad
     * @param {Object} selectors - [[Description]]
     */
    function Notepad(selectors) {
      this.fileName = "Note.txt";
      this.selectors = selectors;
      this.wordWrap = false;
      this.statusBar = false;
      self = this;
    }

    /**
     * Create a new file.
     */
    Notepad.prototype.fileNew = function() {
      self.selectors.textarea.value = "";
      self.selectors.textarea.focus();
    };

    /**
     * Save the document to the computer.
     */
    Notepad.prototype.fileSave = function() {
      // Create a blob object of the contents
      var blob = new Blob([self.selectors.textarea.value], {type: "text/plain"});

      // Internet Explorer/MS Edge
      if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, self.fileName);

      // All other browsers
      } else {
        // Create the download link
        var saveLink = document.createElement("a");
        saveLink.style.display = "none";
        saveLink.setAttribute("href", URL.createObjectURL(blob));
        saveLink.setAttribute("download", self.fileName);
        self.selectors.body.appendChild(saveLink);

        // Start the download and remove the link
        saveLink.click();
        self.selectors.body.removeChild(saveLink);
      }
    };

    /**
     * Save a document to the computer using a custom file name.
     */
    Notepad.prototype.fileSaveAs = function() {
      var newName = prompt("Enter the desired file name").trim();

      // Do not permit a blank name
      if (!/^\s*$/.test(newName)) {
        self.fileName = newName + ".txt";
      }
      self.fileSave();
    };

    /**
     * Print the current document.
     */
    Notepad.prototype.filePrint = function() {
      window.print();
    };

    /**
     * Insert the current time and date into the document
     * at the current cursor position.
     */
    Notepad.prototype.editTimeDate = function() {
      var date = new Date(),
          curHour = date.getHours(),
          curMin  = date.getMinutes(),
          timeOfDay = curHour > 11 ? "PM" : "AM",
          cursorPos = self.selectors.textarea.selectionStart;

      // Midnight
      if (curHour === 0) {
        curHour = "12";

        // Afternoon
      } else if (curHour > 11) {
        curHour -= 12;
      }

      // Pretty print the minutes
      if (curMin < 10) {
        curMin = "0" + curMin;
      }

      // Construct the formatted string
      var dateString = curHour + ":" + curMin + " " + timeOfDay + " " +
                       date.toLocaleDateString();

      // Update the document with the date string
      var front = self.selectors.textarea.value.substring(0, cursorPos),
          back  = self.selectors.textarea.value.substring(cursorPos, self.selectors.textarea.length);

      // Insert the date string into the document
      self.selectors.textarea.value = front + dateString + back;
      self.selectors.textarea.selectionStart = cursorPos;
      self.selectors.textarea.selectionEnd = cursorPos;
      self.selectors.textarea.focus();
    };

    /**
     * Toggle the status bar.
     */
    Notepad.prototype.toggleStatusBar = function() {
      // Word wrap must be disabled
      if (!self.wordWrap) {
        self.selectors.areaEdit.classList.toggle("has-status-bar");
        self.selectors.statusBar.classList.toggle("visible");
        self.statusBar = !self.statusBar;
      }
    };

    /**
     * Toggle word wrap.
     */
    Notepad.prototype.toggleWordWrap = function() {
      // We cannot have the status bar and word wrap enabled
      if (self.statusBar) {
        self.toggleStatusBar();
      }

      self.selectors.textarea.classList.toggle("no-word-wrap");
      self.wordWrap = !self.wordWrap;
    };

    /**
     * Change the UI theme.
     *
     * @param {String} newTheme - The desired theme to use.
     * @returns {Boolean} True if the theme could be changed, false otherwise.
     */
    Notepad.prototype.changeTheme = function(newTheme) {
      var validThemes  = ["win7", "win10"],
          currentTheme = __getCurrentTheme(self.selectors.body);

      // The desired theme is already applied or not available
      if (newTheme === currentTheme || validThemes.indexOf(newTheme) === -1) {
        return false;
      }

      // Apply the desired theme
      self.selectors.body.classList.remove(currentTheme);
      self.selectors.body.classList.add(newTheme);
      return true;
    };

    return Notepad;
  })();

  // Create a new Notepad API instance
  var notepad = new Notepad({
    body: document.querySelector("body"),
    areaEdit: document.querySelector("#area-edit"),
    textarea: QtextArea,
    statusBar: document.querySelector("#area-status-bar"),
  });

  // File > New command
  document.querySelector(".menu-context #action-new").addEventListener("click", notepad.fileNew);

  // File > Save command
  document.querySelector(".menu-context #action-save").addEventListener("click", notepad.fileSave);

  // File > Save As command
  document.querySelector(".menu-context #action-save-as").addEventListener("click", notepad.fileSaveAs);

  // File > Print command
  document.querySelector(".menu-context #action-print").addEventListener("click", notepad.filePrint);

  // Edit > Time/Date
  document.querySelector(".menu-context #action-time-date").addEventListener("click", notepad.editTimeDate);

  // Format > Word Wrap
  // Word wrap is disabled by default
  var QwordWrap = document.querySelector("input#word-wrap");
  QwordWrap.checked = false;
  QwordWrap.addEventListener("click", notepad.toggleWordWrap);

  // View > Status Bar
  // Status bar is disabled by default
  var QstatusBar = document.querySelector("input#status-bar");
  QstatusBar.checked = false;
  QstatusBar.addEventListener("click", notepad.toggleStatusBar);

  // View > Windows X
  var themeWin7  = document.querySelector(".menu-context input#theme-win7"),
      themeWin10 = document.querySelector(".menu-context input#theme-win10");

  // Default to the Windows 10 theme
  themeWin10.checked = true;
  themeWin7.onchange = themeWin10.onchange = function(e) {
    notepad.changeTheme(e.target.id.match(/^theme-(win\d{1,2})/)[1]);
  };
}());
<commit_msg>Rename `selectors` object<commit_after>/* jshint browser: true */
(function() {
  "use strict";
  /**
   * Confirm this is a nav menu item.
   *
   * @returns {Boolean} True if a nav item.
   */
  function isNavItem(id) {
    return /^menu-(?:\w+?)$/.test(id);
  }

  /**
   * Hide the current menu.
   */
  function hideNavMenu() {
    var menuVisible = document.querySelector(".menu-context.visible");
    var menuActive = document.querySelector(".menu .active");

    // Hide the currently visible menu
    if (menuVisible) {
      menuVisible.classList.remove("visible");
    }

    // Un-highlight the current nav item
    if (menuActive) {
      menuActive.classList.remove("active");
    }
  }

  var menusAreVisible = false,
      Qbody = document.querySelector("body"),
      Qmenu = document.querySelector(".menu"),
      QtextArea = document.querySelector("textarea");

  Qmenu.addEventListener("mouseover", function(e) {
    // Make sure we are on a nav item
    if (isNavItem(e.target.id)) {
      hideNavMenu();

      // Only display the menus if we are allowed to
      if (menusAreVisible) {
        // Display the currently hovered-over menu
        var contextMenu = e.target.id.match(/^menu-(\w+?)$/)[1];
        document.querySelector(".menu-context." +  contextMenu).classList.add("visible");
        e.target.classList.add("active");
      }
    }
  });

  Qmenu.addEventListener("click", function(e) {
    // Close the menu if the label is clicked again
    if (isNavItem(e.target.id) && menusAreVisible) {
      menusAreVisible = false;
      hideNavMenu();
      return;
    }

    // Make sure the desired menu is not already visible
    if (isNavItem(e.target.id) && !e.target.classList.contains("visible")) {
      // Menus are allowed to be shown
      menusAreVisible = true;

      // Display the desired menu
      var contextMenu = e.target.id.match(/^menu-(\w+?)$/)[1];
      document.querySelector(".menu-context." +  contextMenu).classList.add("visible");
      e.target.classList.add("active");
    }
   });

  Qbody.addEventListener("click", function(e) {
    if (!isNavItem(e.target.id) && !e.target.classList.contains("menu-disabled") &&
        !e.target.classList.contains("blank")) {
      // Menus are not allowed to be shown at this time
      if (menusAreVisible) {
        menusAreVisible = false;
        hideNavMenu();
      }
    }
  });

  var Notepad = (function() {
    var self = null;

    /**
     * Get the class of the current theme.
     *
     * @private
     * @returns {String}
     */
    function __getCurrentTheme(body) {
      return body.className.match(/^win\d{1,2}$/)[0];
    }

    /**
     * Create a Notepad API instance.
     *
     * @constructs Notepad
     * @param {Object} ele - [[Description]]
     */
    function Notepad(ele) {
      this.fileName = "Note.txt";
      this.ele = ele;
      this.wordWrap = false;
      this.statusBar = false;
      self = this;
    }

    /**
     * Create a new file.
     */
    Notepad.prototype.fileNew = function() {
      self.ele.textarea.value = "";
      self.ele.textarea.focus();
    };

    /**
     * Save the document to the computer.
     */
    Notepad.prototype.fileSave = function() {
      // Create a blob object of the contents
      var blob = new Blob([self.ele.textarea.value], {type: "text/plain"});

      // Internet Explorer/MS Edge
      if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, self.fileName);

      // All other browsers
      } else {
        // Create the download link
        var saveLink = document.createElement("a");
        saveLink.style.display = "none";
        saveLink.setAttribute("href", URL.createObjectURL(blob));
        saveLink.setAttribute("download", self.fileName);
        self.ele.body.appendChild(saveLink);

        // Start the download and remove the link
        saveLink.click();
        self.ele.body.removeChild(saveLink);
      }
    };

    /**
     * Save a document to the computer using a custom file name.
     */
    Notepad.prototype.fileSaveAs = function() {
      var newName = prompt("Enter the desired file name").trim();

      // Do not permit a blank name
      if (!/^\s*$/.test(newName)) {
        self.fileName = newName + ".txt";
      }
      self.fileSave();
    };

    /**
     * Print the current document.
     */
    Notepad.prototype.filePrint = function() {
      window.print();
    };

    /**
     * Insert the current time and date into the document
     * at the current cursor position.
     */
    Notepad.prototype.editTimeDate = function() {
      var date = new Date(),
          curHour = date.getHours(),
          curMin  = date.getMinutes(),
          timeOfDay = curHour > 11 ? "PM" : "AM",
          cursorPos = self.ele.textarea.selectionStart;

      // Midnight
      if (curHour === 0) {
        curHour = "12";

        // Afternoon
      } else if (curHour > 11) {
        curHour -= 12;
      }

      // Pretty print the minutes
      if (curMin < 10) {
        curMin = "0" + curMin;
      }

      // Construct the formatted string
      var dateString = curHour + ":" + curMin + " " + timeOfDay + " " +
                       date.toLocaleDateString();

      // Update the document with the date string
      var front = self.ele.textarea.value.substring(0, cursorPos),
          back  = self.ele.textarea.value.substring(cursorPos, self.ele.textarea.length);

      // Insert the date string into the document
      self.ele.textarea.value = front + dateString + back;
      self.ele.textarea.selectionStart = cursorPos;
      self.ele.textarea.selectionEnd = cursorPos;
      self.ele.textarea.focus();
    };

    /**
     * Toggle the status bar.
     */
    Notepad.prototype.toggleStatusBar = function() {
      // Word wrap must be disabled
      if (!self.wordWrap) {
        self.ele.areaEdit.classList.toggle("has-status-bar");
        self.ele.statusBar.classList.toggle("visible");
        self.statusBar = !self.statusBar;
      }
    };

    /**
     * Toggle word wrap.
     */
    Notepad.prototype.toggleWordWrap = function() {
      // We cannot have the status bar and word wrap enabled
      if (self.statusBar) {
        self.toggleStatusBar();
      }

      self.ele.textarea.classList.toggle("no-word-wrap");
      self.wordWrap = !self.wordWrap;
    };

    /**
     * Change the UI theme.
     *
     * @param {String} newTheme - The desired theme to use.
     * @returns {Boolean} True if the theme could be changed, false otherwise.
     */
    Notepad.prototype.changeTheme = function(newTheme) {
      var validThemes  = ["win7", "win10"],
          currentTheme = __getCurrentTheme(self.ele.body);

      // The desired theme is already applied or not available
      if (newTheme === currentTheme || validThemes.indexOf(newTheme) === -1) {
        return false;
      }

      // Apply the desired theme
      self.ele.body.classList.remove(currentTheme);
      self.ele.body.classList.add(newTheme);
      return true;
    };

    return Notepad;
  })();

  // Create a new Notepad API instance
  var notepad = new Notepad({
    body: document.querySelector("body"),
    areaEdit: document.querySelector("#area-edit"),
    textarea: QtextArea,
    statusBar: document.querySelector("#area-status-bar"),
  });

  // File > New command
  document.querySelector(".menu-context #action-new").addEventListener("click", notepad.fileNew);

  // File > Save command
  document.querySelector(".menu-context #action-save").addEventListener("click", notepad.fileSave);

  // File > Save As command
  document.querySelector(".menu-context #action-save-as").addEventListener("click", notepad.fileSaveAs);

  // File > Print command
  document.querySelector(".menu-context #action-print").addEventListener("click", notepad.filePrint);

  // Edit > Time/Date
  document.querySelector(".menu-context #action-time-date").addEventListener("click", notepad.editTimeDate);

  // Format > Word Wrap
  // Word wrap is disabled by default
  var QwordWrap = document.querySelector("input#word-wrap");
  QwordWrap.checked = false;
  QwordWrap.addEventListener("click", notepad.toggleWordWrap);

  // View > Status Bar
  // Status bar is disabled by default
  var QstatusBar = document.querySelector("input#status-bar");
  QstatusBar.checked = false;
  QstatusBar.addEventListener("click", notepad.toggleStatusBar);

  // View > Windows X
  var themeWin7  = document.querySelector(".menu-context input#theme-win7"),
      themeWin10 = document.querySelector(".menu-context input#theme-win10");

  // Default to the Windows 10 theme
  themeWin10.checked = true;
  themeWin7.onchange = themeWin10.onchange = function(e) {
    notepad.changeTheme(e.target.id.match(/^theme-(win\d{1,2})/)[1]);
  };
}());
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import styled from 'styled-components';
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import { ReactComponent as CloseIcon } from '../../icons/close.svg';
import { Z_INDEX } from '../../constants';
import { Pill } from '../pill';
import { DROPDOWN_ITEM_PROP_TYPE } from '../types';
import { ColorDot } from '../colorDot';

export const Panel = styled.div`
  ${({ isOpen, theme }) => `
    align-items: flex-start;
    background-color: ${theme.colors.white};
    border-radius: 8px;
    box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.25);
    display: flex;
    flex-direction: column;
    opacity: ${isOpen ? 1 : 0};
    overflow: hidden;
    padding: 10px 20px;
    margin: 10px 0 0;
    position: absolute;
    pointer-events: ${isOpen ? 'auto' : 'none'};
    transform: ${isOpen ? 'translate3d(0, 0, 0)' : 'translate3d(0, -1rem, 0)'};
    z-index: ${Z_INDEX.POPOVER_PANEL};
    width: ${theme.popoverPanel.desktopWidth}px;

    @media ${theme.breakpoint.tablet} {
      width: ${theme.popoverPanel.tabletWidth}px;
    }

    @media ${theme.breakpoint.desktop} {
      width: ${theme.popoverPanel.desktopWidth}px;
    }
  `}
`;

Panel.propTypes = {
  isOpen: PropTypes.bool,
};

const PillFieldset = styled.fieldset`
  width: 100%;
  margin: 20px 0 0 0;
  padding: 0;
  border: none;
  > label {
    margin: 0 10px 14px 0;
  }
`;

const visuallyHiddenStyles = {
  position: 'absolute',
  height: '1px',
  width: '1px',
  overflow: 'hidden',
  clip: 'rect(1px, 1px, 1px, 1px)',
  'white-space': 'nowrap',
};

const Legend = styled.legend`
  ${visuallyHiddenStyles}
`;

const KeyboardCloseOnly = styled.button`
  ${visuallyHiddenStyles}
  &:focus {
    clip: unset;
    align-self: flex-end;
    border: ${({ theme }) => theme.borders.action};
    border-radius: 50%;
    height: 20px;
    width: 20px;
    padding: 2px;
    > svg {
      padding: 2px;
    }
  }
`;

const PopoverPanel = ({ onClose, isOpen, title, items, onSelect }) => {
  return (
    <Panel isOpen={isOpen}>
      {isOpen && (
        <>
          <KeyboardCloseOnly
            onClick={onClose}
            data-testid={'popover-close-btn'}
            ariaDescription={__('close menu', 'web-stories')}
          >
            <CloseIcon width={14} height="14" />
          </KeyboardCloseOnly>
          <PillFieldset data-testid={'pill-fieldset'}>
            <Legend title={`options for ${title}`} />
            {items.map(
              ({ label, selected, value, hex, disabled = false }, index) => {
                return (
                  <Pill
                    data-testid={'popover-pill'}
                    key={`${value}_${index}`}
                    inputType="checkbox"
                    name={`${title}_pillGroup_${value}`}
                    onClick={onSelect}
                    value={value}
                    isSelected={selected}
                    disabled={disabled}
                  >
                    {hex ? <ColorDot color={hex} /> : label}
                  </Pill>
                );
              }
            )}
          </PillFieldset>
        </>
      )}
    </Panel>
  );
};

PopoverPanel.propTypes = {
  title: PropTypes.string.isRequired,
  onSelect: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  isOpen: PropTypes.bool,
  items: PropTypes.arrayOf(DROPDOWN_ITEM_PROP_TYPE),
};

export default PopoverPanel;
<commit_msg>change ariaDescription to ariaLabel on keyboard close button<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import styled from 'styled-components';
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import { ReactComponent as CloseIcon } from '../../icons/close.svg';
import { Z_INDEX } from '../../constants';
import { Pill } from '../pill';
import { DROPDOWN_ITEM_PROP_TYPE } from '../types';
import { ColorDot } from '../colorDot';

export const Panel = styled.div`
  ${({ isOpen, theme }) => `
    align-items: flex-start;
    background-color: ${theme.colors.white};
    border-radius: 8px;
    box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.25);
    display: flex;
    flex-direction: column;
    opacity: ${isOpen ? 1 : 0};
    overflow: hidden;
    padding: 10px 20px;
    margin: 10px 0 0;
    position: absolute;
    pointer-events: ${isOpen ? 'auto' : 'none'};
    transform: ${isOpen ? 'translate3d(0, 0, 0)' : 'translate3d(0, -1rem, 0)'};
    z-index: ${Z_INDEX.POPOVER_PANEL};
    width: ${theme.popoverPanel.desktopWidth}px;

    @media ${theme.breakpoint.tablet} {
      width: ${theme.popoverPanel.tabletWidth}px;
    }

    @media ${theme.breakpoint.desktop} {
      width: ${theme.popoverPanel.desktopWidth}px;
    }
  `}
`;

Panel.propTypes = {
  isOpen: PropTypes.bool,
};

const PillFieldset = styled.fieldset`
  width: 100%;
  margin: 20px 0 0 0;
  padding: 0;
  border: none;
  > label {
    margin: 0 10px 14px 0;
  }
`;

const visuallyHiddenStyles = {
  position: 'absolute',
  height: '1px',
  width: '1px',
  overflow: 'hidden',
  clip: 'rect(1px, 1px, 1px, 1px)',
  'white-space': 'nowrap',
};

const Legend = styled.legend`
  ${visuallyHiddenStyles}
`;

const KeyboardCloseOnly = styled.button`
  ${visuallyHiddenStyles}
  &:focus {
    clip: unset;
    align-self: flex-end;
    border: ${({ theme }) => theme.borders.action};
    border-radius: 50%;
    height: 20px;
    width: 20px;
    padding: 2px;
    > svg {
      padding: 2px;
    }
  }
`;

const PopoverPanel = ({ onClose, isOpen, title, items, onSelect }) => {
  return (
    <Panel isOpen={isOpen}>
      {isOpen && (
        <>
          <KeyboardCloseOnly
            onClick={onClose}
            data-testid={'popover-close-btn'}
            ariaLabel={__('close menu', 'web-stories')}
          >
            <CloseIcon width={14} height="14" />
          </KeyboardCloseOnly>
          <PillFieldset data-testid={'pill-fieldset'}>
            <Legend title={`options for ${title}`} />
            {items.map(
              ({ label, selected, value, hex, disabled = false }, index) => {
                return (
                  <Pill
                    data-testid={'popover-pill'}
                    key={`${value}_${index}`}
                    inputType="checkbox"
                    name={`${title}_pillGroup_${value}`}
                    onClick={onSelect}
                    value={value}
                    isSelected={selected}
                    disabled={disabled}
                  >
                    {hex ? <ColorDot color={hex} /> : label}
                  </Pill>
                );
              }
            )}
          </PillFieldset>
        </>
      )}
    </Panel>
  );
};

PopoverPanel.propTypes = {
  title: PropTypes.string.isRequired,
  onSelect: PropTypes.func.isRequired,
  onClose: PropTypes.func.isRequired,
  isOpen: PropTypes.bool,
  items: PropTypes.arrayOf(DROPDOWN_ITEM_PROP_TYPE),
};

export default PopoverPanel;
<|endoftext|>


<commit_before>Version = { id: '36ea3d0' };
<commit_msg>Bump up version<commit_after>Version = { id: 'c8eb6e8' };
<|endoftext|>


<commit_before>var assert = require("assert"),
    hashkit = require("../hashkit.js");

describe("Hashkit", function(){
    describe("defaults", function(){
        var h = new hashkit();
        it("should have the correct defaults", function(){
            assert.equal(h.options.chars, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
            assert.equal(h.options.padding, 3);
            assert.equal(h.options.seed, 123456789);
            assert.equal(h.options.shuffle, false);
            assert.equal(h.options.mask, false);
        });
    });

    describe("encoding and decoding", function(){
        var h = new hashkit();
        it("should encode and decode successfully", function(){
            assert.equal(h.encode(1), "b");
            assert.equal(h.encode(10), "k");
            assert.equal(h.encode(100), "bM");
            assert.equal(h.encode(1000), "qi");
            assert.equal(h.decode("b"), 1);
            assert.equal(h.decode("k"), 10);
            assert.equal(h.decode("bM"), 100);
            assert.equal(h.decode("qi"), 1000);
        });
    });

    describe("character shuffling", function(){
        var h = new hashkit({"shuffle": true});
        it("should shuffle characters", function(){
            assert.equal(h.options.shuffle, true);
            assert.equal(h.options.chars, "WLgvI6CN7tqi8xfdFJZYDVeuP5K0kpAhmTEG2SjH39cXoyMzQbsraUBwl1OR4n");
            assert.equal(h.encode(1), "L");
            assert.equal(h.encode(10), "q");
            assert.equal(h.encode(100), "Lj");
            assert.equal(h.encode(1000), "F7");
            assert.equal(h.decode("L"), 1);
            assert.equal(h.decode("q"), 10);
            assert.equal(h.decode("Lj"), 100);
            assert.equal(h.decode("F7"), 1000);
        });
    });

    describe("number masking", function(){
        var h = new hashkit({"mask": true});
        it("should mask the real numbers", function(){
            assert.equal(h.options.mask, true);
            assert.equal(h.encode(1), "cop");
            assert.equal(h.encode(10), "xjO");
            assert.equal(h.encode(100), "bcrE");
            assert.equal(h.encode(1000), "KKTs");
            assert.equal(h.decode("cop"), 1);
            assert.equal(h.decode("xjO"), 10);
            assert.equal(h.decode("bcrE"), 100);
            assert.equal(h.decode("KKTs"), 1000);
        });
    });

    describe("random seeding", function(){
        var h = new hashkit({"shuffle": true, "mask": true, "seed": 99999});
        it("should randomize the output", function(){
            assert.equal(h.options.chars, "yWjaFqLb8uIliZz7vr2REC30MPUhSxtpY1J6TfswGcmXdV9KDnegoHQkAN54OB");
            assert.equal(h.encode(1), "WT7");
            assert.equal(h.encode(2), "AO");
            assert.equal(h.encode(3), "UB");
        });
    });
});
<commit_msg>Update mocha tests.<commit_after>var assert = require("assert"),
    hashkit = require("../hashkit.js");

describe("Hashkit", function(){
    describe("defaults", function(){
        var h = new hashkit();
        it("should have the correct defaults", function(){
            assert.equal(h.options.chars, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
            assert.equal(h.options.padding, 3);
            assert.equal(h.options.seed, 123456789);
            assert.equal(h.options.shuffle, false);
            assert.equal(h.options.mask, false);
        });
    });

    describe("encoding and decoding", function(){
        var h = new hashkit();
        it("should encode and decode successfully", function(){
            assert.equal(h.encode(1), "b");
            assert.equal(h.encode(10), "k");
            assert.equal(h.encode(100), "bM");
            assert.equal(h.encode(1000), "qi");
            assert.equal(h.decode("b"), 1);
            assert.equal(h.decode("k"), 10);
            assert.equal(h.decode("bM"), 100);
            assert.equal(h.decode("qi"), 1000);
        });
    });

    describe("salt string", function(){
        var h = new hashkit("my salt string");
        it("should encode and decode successfully", function(){
            assert.equal(h.encode(1), "Pa");
            assert.equal(h.encode(10), "8Ep");
            assert.equal(h.encode(100), "8zmN");
            assert.equal(h.encode(1000), "2c54");
            assert.equal(h.decode("Pa"), 1);
            assert.equal(h.decode("8Ep"), 10);
            assert.equal(h.decode("8zmN"), 100);
            assert.equal(h.decode("2c54"), 1000);
        });
    });

    describe("character shuffling", function(){
        var h = new hashkit({"shuffle": true});
        it("should shuffle characters", function(){
            assert.equal(h.options.shuffle, true);
            assert.equal(h.options.chars, "WLgvI6CN7tqi8xfdFJZYDVeuP5K0kpAhmTEG2SjH39cXoyMzQbsraUBwl1OR4n");
            assert.equal(h.encode(1), "L");
            assert.equal(h.encode(10), "q");
            assert.equal(h.encode(100), "Lj");
            assert.equal(h.encode(1000), "F7");
            assert.equal(h.decode("L"), 1);
            assert.equal(h.decode("q"), 10);
            assert.equal(h.decode("Lj"), 100);
            assert.equal(h.decode("F7"), 1000);
        });
    });

    describe("number masking", function(){
        var h = new hashkit({"mask": true});
        it("should mask the real numbers", function(){
            assert.equal(h.options.mask, true);
            assert.equal(h.encode(1), "cop");
            assert.equal(h.encode(10), "xjO");
            assert.equal(h.encode(100), "bcrE");
            assert.equal(h.encode(1000), "KKTs");
            assert.equal(h.decode("cop"), 1);
            assert.equal(h.decode("xjO"), 10);
            assert.equal(h.decode("bcrE"), 100);
            assert.equal(h.decode("KKTs"), 1000);
        });
    });

    describe("random seeding", function(){
        var h = new hashkit({"shuffle": true, "mask": true, "seed": 99999});
        it("should randomize the output", function(){
            assert.equal(h.options.chars, "yWjaFqLb8uIliZz7vr2REC30MPUhSxtpY1J6TfswGcmXdV9KDnegoHQkAN54OB");
            assert.equal(h.encode(1), "WT7");
            assert.equal(h.encode(2), "AO");
            assert.equal(h.encode(3), "UB");
        });
    });
});
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * This view displays options for importing/exporting the captured data. Its
 * primarily usefulness is to allow users to copy-paste their data in an easy
 * to read format for bug reports.
 *
 *   - Has a button to generate a text report.
 *   - Has a button to generate a raw JSON dump (most useful for testing).
 *
 *  @constructor
 */
function DataView(mainBoxId, outputTextBoxId, exportTextButtonId) {
  DivView.call(this, mainBoxId);

  this.textPre_ = document.getElementById(outputTextBoxId);
  var exportTextButton = document.getElementById(exportTextButtonId);

  exportTextButton.onclick = this.onExportToText_.bind(this);
}

inherits(DataView, DivView);

/**
 * Presents the captured data as formatted text.
 */
DataView.prototype.onExportToText_ = function() {
  this.setText_("Generating...");

  var text = [];

  // Print some basic information about our environment.
  text.push('Data exported on: ' + (new Date()).toLocaleString());
  text.push('');
  text.push('Number of passively captured events: ' +
            g_browser.getAllPassivelyCapturedEvents().length);
  text.push('Number of actively captured events: ' +
            g_browser.getAllActivelyCapturedEvents().length);
  text.push('');

  text.push('Chrome version: ' + ClientInfo.version +
            ' (' + ClientInfo.official +
            ' ' + ClientInfo.cl +
            ') ' + ClientInfo.version_mod);
  text.push('Command line switches: ' + ClientInfo.command_line);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Proxy settings');
  text.push('----------------------------------------------');
  text.push('');

  text.push(g_browser.proxySettings_.currentData_);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Bad proxies cache');
  text.push('----------------------------------------------');

  var badProxiesList = g_browser.badProxies_.currentData_;
  if (badProxiesList.length == 0) {
    text.push('');
    text.push('None');
  } else {
    for (var i = 0; i < badProxiesList.length; ++i) {
      var e = badProxiesList[i];
      text.push('');
      text.push('(' + (i+1) + ')');
      text.push('Proxy: ' + e.proxy_uri);
      text.push('Bad until: ' + this.formatExpirationTime_(e.bad_until));
    }
  }

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Host resolver cache');
  text.push('----------------------------------------------');
  text.push('');

  var hostResolverCache = g_browser.hostResolverCache_.currentData_;

  text.push('Capcity: ' + hostResolverCache.capacity);
  text.push('Time to live for successful resolves (ms): ' +
            hostResolverCache.ttl_success_ms);
  text.push('Time to live for failed resolves (ms): ' +
            hostResolverCache.ttl_failure_ms);

  if (hostResolverCache.entries.length > 0) {
    for (var i = 0; i < hostResolverCache.entries.length; ++i) {
      var e = hostResolverCache.entries[i];

      text.push('');
      text.push('(' + (i+1) + ')');
      text.push('Hostname: ' + e.hostname);
      text.push('Address family: ' + e.address_family);

      if (e.error != undefined) {
         text.push('Error: ' + e.error);
      } else {
        for (var j = 0; j < e.addresses.length; ++j) {
          text.push('Address ' + (j + 1) + ': ' + e.addresses[j]);
        }
      }

      text.push('Valid until: ' + this.formatExpirationTime_(e.expiration));
    }
  } else {
    text.push('');
    text.push('None');
  }

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Requests');
  text.push('----------------------------------------------');
  text.push('');

  this.appendRequestsPrintedAsText_(text);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Http cache stats');
  text.push('----------------------------------------------');
  text.push('');

  var httpCacheStats = g_browser.httpCacheInfo_.currentData_.stats;
  for (var statName in httpCacheStats)
    text.push(statName + ': ' + httpCacheStats[statName]);

  // Open a new window to display this text.
  this.setText_(text.join('\n'));
};

DataView.prototype.appendRequestsPrintedAsText_ = function(out) {
  // Concatenate the passively captured events with the actively captured events
  // into a single array.
  var allEvents = g_browser.getAllPassivelyCapturedEvents().concat(
      g_browser.getAllActivelyCapturedEvents());

  // Group the events into buckets by source ID, and buckets by source type.
  var sourceIds = [];
  var sourceIdToEventList = {};
  var sourceTypeToSourceIdList = {}

  for (var i = 0; i < allEvents.length; ++i) {
    var e = allEvents[i];
    var eventList = sourceIdToEventList[e.source.id];
    if (!eventList) {
      eventList = [];
      sourceIdToEventList[e.source.id] = eventList;

      // Update sourceIds
      sourceIds.push(e.source.id);

      // Update the sourceTypeToSourceIdList list.
      var idList = sourceTypeToSourceIdList[e.source.type];
      if (!idList) {
        idList = [];
        sourceTypeToSourceIdList[e.source.type] = idList;
      }
      idList.push(e.source.id);
    }
    eventList.push(e);
  }

  // For each source (ordered by when that source was first started).
  for (var i = 0; i < sourceIds.length; ++i) {
    var sourceId = sourceIds[i];
    var eventList = sourceIdToEventList[sourceId];
    var sourceType = eventList[0].source.type;

    out.push('------------------------------');
    out.push(getKeyWithValue(LogSourceType, sourceType) +
             ' (id=' + sourceId + ')');
    out.push('------------------------------');

    out.push(PrintSourceEntriesAsText(eventList));
  }
};

/**
 * Helper function to set this view's content to |text|.
 */
DataView.prototype.setText_ = function(text) {
  this.textPre_.innerHTML = '';
  addTextNode(this.textPre_, text);
};

/**
 * Format a time ticks count as a timestamp.
 */
DataView.prototype.formatExpirationTime_ = function(timeTicks) {
  var d = g_browser.convertTimeTicksToDate(timeTicks);
  var isExpired = d.getTime() < (new Date()).getTime();
  return 't=' + d.getTime() + (isExpired ? ' [EXPIRED]' : '');
};

<commit_msg>Cleanup: Reword a label from "command line switches" to "command line", as that is more accurate.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * This view displays options for importing/exporting the captured data. Its
 * primarily usefulness is to allow users to copy-paste their data in an easy
 * to read format for bug reports.
 *
 *   - Has a button to generate a text report.
 *   - Has a button to generate a raw JSON dump (most useful for testing).
 *
 *  @constructor
 */
function DataView(mainBoxId, outputTextBoxId, exportTextButtonId) {
  DivView.call(this, mainBoxId);

  this.textPre_ = document.getElementById(outputTextBoxId);
  var exportTextButton = document.getElementById(exportTextButtonId);

  exportTextButton.onclick = this.onExportToText_.bind(this);
}

inherits(DataView, DivView);

/**
 * Presents the captured data as formatted text.
 */
DataView.prototype.onExportToText_ = function() {
  this.setText_("Generating...");

  var text = [];

  // Print some basic information about our environment.
  text.push('Data exported on: ' + (new Date()).toLocaleString());
  text.push('');
  text.push('Number of passively captured events: ' +
            g_browser.getAllPassivelyCapturedEvents().length);
  text.push('Number of actively captured events: ' +
            g_browser.getAllActivelyCapturedEvents().length);
  text.push('');

  text.push('Chrome version: ' + ClientInfo.version +
            ' (' + ClientInfo.official +
            ' ' + ClientInfo.cl +
            ') ' + ClientInfo.version_mod);
  text.push('Command line: ' + ClientInfo.command_line);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Proxy settings');
  text.push('----------------------------------------------');
  text.push('');

  text.push(g_browser.proxySettings_.currentData_);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Bad proxies cache');
  text.push('----------------------------------------------');

  var badProxiesList = g_browser.badProxies_.currentData_;
  if (badProxiesList.length == 0) {
    text.push('');
    text.push('None');
  } else {
    for (var i = 0; i < badProxiesList.length; ++i) {
      var e = badProxiesList[i];
      text.push('');
      text.push('(' + (i+1) + ')');
      text.push('Proxy: ' + e.proxy_uri);
      text.push('Bad until: ' + this.formatExpirationTime_(e.bad_until));
    }
  }

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Host resolver cache');
  text.push('----------------------------------------------');
  text.push('');

  var hostResolverCache = g_browser.hostResolverCache_.currentData_;

  text.push('Capcity: ' + hostResolverCache.capacity);
  text.push('Time to live for successful resolves (ms): ' +
            hostResolverCache.ttl_success_ms);
  text.push('Time to live for failed resolves (ms): ' +
            hostResolverCache.ttl_failure_ms);

  if (hostResolverCache.entries.length > 0) {
    for (var i = 0; i < hostResolverCache.entries.length; ++i) {
      var e = hostResolverCache.entries[i];

      text.push('');
      text.push('(' + (i+1) + ')');
      text.push('Hostname: ' + e.hostname);
      text.push('Address family: ' + e.address_family);

      if (e.error != undefined) {
         text.push('Error: ' + e.error);
      } else {
        for (var j = 0; j < e.addresses.length; ++j) {
          text.push('Address ' + (j + 1) + ': ' + e.addresses[j]);
        }
      }

      text.push('Valid until: ' + this.formatExpirationTime_(e.expiration));
    }
  } else {
    text.push('');
    text.push('None');
  }

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Requests');
  text.push('----------------------------------------------');
  text.push('');

  this.appendRequestsPrintedAsText_(text);

  text.push('');
  text.push('----------------------------------------------');
  text.push(' Http cache stats');
  text.push('----------------------------------------------');
  text.push('');

  var httpCacheStats = g_browser.httpCacheInfo_.currentData_.stats;
  for (var statName in httpCacheStats)
    text.push(statName + ': ' + httpCacheStats[statName]);

  // Open a new window to display this text.
  this.setText_(text.join('\n'));
};

DataView.prototype.appendRequestsPrintedAsText_ = function(out) {
  // Concatenate the passively captured events with the actively captured events
  // into a single array.
  var allEvents = g_browser.getAllPassivelyCapturedEvents().concat(
      g_browser.getAllActivelyCapturedEvents());

  // Group the events into buckets by source ID, and buckets by source type.
  var sourceIds = [];
  var sourceIdToEventList = {};
  var sourceTypeToSourceIdList = {}

  for (var i = 0; i < allEvents.length; ++i) {
    var e = allEvents[i];
    var eventList = sourceIdToEventList[e.source.id];
    if (!eventList) {
      eventList = [];
      sourceIdToEventList[e.source.id] = eventList;

      // Update sourceIds
      sourceIds.push(e.source.id);

      // Update the sourceTypeToSourceIdList list.
      var idList = sourceTypeToSourceIdList[e.source.type];
      if (!idList) {
        idList = [];
        sourceTypeToSourceIdList[e.source.type] = idList;
      }
      idList.push(e.source.id);
    }
    eventList.push(e);
  }

  // For each source (ordered by when that source was first started).
  for (var i = 0; i < sourceIds.length; ++i) {
    var sourceId = sourceIds[i];
    var eventList = sourceIdToEventList[sourceId];
    var sourceType = eventList[0].source.type;

    out.push('------------------------------');
    out.push(getKeyWithValue(LogSourceType, sourceType) +
             ' (id=' + sourceId + ')');
    out.push('------------------------------');

    out.push(PrintSourceEntriesAsText(eventList));
  }
};

/**
 * Helper function to set this view's content to |text|.
 */
DataView.prototype.setText_ = function(text) {
  this.textPre_.innerHTML = '';
  addTextNode(this.textPre_, text);
};

/**
 * Format a time ticks count as a timestamp.
 */
DataView.prototype.formatExpirationTime_ = function(timeTicks) {
  var d = g_browser.convertTimeTicksToDate(timeTicks);
  var isExpired = d.getTime() < (new Date()).getTime();
  return 't=' + d.getTime() + (isExpired ? ' [EXPIRED]' : '');
};

<|endoftext|>


<commit_before>var slug = require('slug-component'),
    moment = require('moment'),
    _ = require('underscore');

function appendMetadata(config) {
    return function (files, lbr, done) {
        var metadata = lbr.metadata();

        //TODO: Consolidate how we gather tags!
        //redo simple array, and metadata.collections.tags
        var tags = [];
        metadata.tags = {};

        var append = function (collectionItem, urlPrefix) {
            var slugVal = slug(collectionItem.title);
            var datePart = moment(collectionItem.date).utc().format(config.datePattern);

            collectionItem.url = urlPrefix + datePart + '/' + slugVal;

            _.each(collectionItem.tags, function (iTag) {
                tags.push(iTag);

                if(!metadata.tags.hasOwnProperty(iTag)){
                    metadata.tags[iTag] = {
                        label: iTag,
                        posts:[]
                    };
                }
                metadata.tags[iTag].posts.push(collectionItem);
            });
        };

        var BLOG_TOP_N = 3;
        var PROJECTS_TOP_N = 3;
        var i = 0;
        var j = 0;

        metadata.blog.pinned = [];
        metadata.blog.forEach(function (_post) {
            append(_post, '/blog/');

            if (i < BLOG_TOP_N) {
                ++i;
                metadata.blog.pinned.push(_post);
            }
        });

        metadata.projects.pinned = [];
        metadata.projects.forEach(function (_post) {
            append(_post, '/projects/');

            if (j < PROJECTS_TOP_N) {
                ++j;
                metadata.projects.pinned.push(_post);
            }
        });

        metadata.collections.tags = _.uniq(tags);

        done();
    };
}

module.exports = appendMetadata;<commit_msg>LIB: appendMetadata refactoring<commit_after>var slug = require('slug-component'),
    moment = require('moment'),
    extend = require('gextend'),
    _ = require('underscore');

var DEFAULTS = {
    featuredItems: 3
}

function appendMetadata(config) {

    config = extend({}, DEFAULTS, config);

    return function (files, lbr, done) {
        var metadata = lbr.metadata();

        //TODO: Consolidate how we gather tags!
        //redo simple array, and metadata.collections.tags
        var tags = [];
        metadata.tags = {};

        function append(collectionItem, urlPrefix) {
            var slugVal = slug(collectionItem.title);
            var datePart = moment(collectionItem.date).utc().format(config.datePattern);

            collectionItem.url = urlPrefix + datePart + '/' + slugVal;

            _.each(collectionItem.tags, function (iTag) {
                tags.push(iTag);

                if(!metadata.tags.hasOwnProperty(iTag)){
                    metadata.tags[iTag] = {
                        label: iTag,
                        posts:[]
                    };
                }

                metadata.tags[iTag].posts.push(collectionItem);
            });
            //BUG: Without this, items without tags shows the
            //tags metadata object. We have to clean this whole
            //thing up!!!
            if(!collectionItem.tags) collectionItem.tags = [];
        }

        function featuredItemsForSection(sectionId, total, metadata){
            var index = 0,
                section = metadata[sectionId],
                sectionUrl = '/' + sectionId + '/';

            section.pinned = [];
            section.forEach(function (_post) {
                append(_post, sectionUrl);

                if (index < total) {
                    ++index;
                    section.pinned.push(_post);
                }
            });
        }

        featuredItemsForSection('blog', config.featuredItems, metadata);
        // var index = 0;

        // metadata.blog.pinned = [];
        // metadata.blog.forEach(function (_post) {
        //     append(_post, '/blog/');

        //     if (index < config.featuredItems) {
        //         ++index;
        //         metadata.blog.pinned.push(_post);
        //     }
        // });

        featuredItemsForSection('projects', config.featuredItems, metadata);
        // index = 0;
        // metadata.projects.pinned = [];
        // metadata.projects.forEach(function (_post) {
        //     append(_post, '/projects/');

        //     if (index < config.featuredItems) {
        //         ++index;
        //         metadata.projects.pinned.push(_post);
        //     }
        // });

        metadata.collections.tags = _.uniq(tags);

        done();
    };
}

module.exports = appendMetadata;<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/**
* Blas level 1 routine to multiply `x` by a constant.
*
* @module @stdlib/blas/base/dscal
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
* var dscal = require( '@stdlib/blas/base/dscal' );
*
* var x = new Float64Array( [ -2.0, 1.0, 3.0, -5.0, 4.0, 0.0, -1.0, -3.0 ] );
*
* dscal( x.length, 5.0, x, 1 );
* // x => <Float64Array>[ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ]
*
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
* var dscal = require( '@stdlib/blas/base/dscal' );
*
* var x = new Float64Array( [ -2.0, 1.0, 3.0, -5.0, 4.0, 0.0, -1.0, -3.0 ] );
*
* dscal.ndarray( x.length, 5.0, x, 1, 0 );
* // x => <Float64Array>[ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ]
*/

// MODULES //

var dscal = require( './main.js' );

// EXPORTS //

module.exports = dscal;
<commit_msg>Remove extra linebreak<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/**
* Blas level 1 routine to multiply `x` by a constant.
*
* @module @stdlib/blas/base/dscal
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
* var dscal = require( '@stdlib/blas/base/dscal' );
*
* var x = new Float64Array( [ -2.0, 1.0, 3.0, -5.0, 4.0, 0.0, -1.0, -3.0 ] );
*
* dscal( x.length, 5.0, x, 1 );
* // x => <Float64Array>[ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ]
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
* var dscal = require( '@stdlib/blas/base/dscal' );
*
* var x = new Float64Array( [ -2.0, 1.0, 3.0, -5.0, 4.0, 0.0, -1.0, -3.0 ] );
*
* dscal.ndarray( x.length, 5.0, x, 1, 0 );
* // x => <Float64Array>[ -10.0, 5.0, 15.0, -25.0, 20.0, 0.0, -5.0, -15.0 ]
*/

// MODULES //

var dscal = require( './main.js' );

// EXPORTS //

module.exports = dscal;
<|endoftext|>


<commit_before>module('legind.instrumentation').requires('lively.ast.Rewriting').toRun(function() {

Object.subclass('legind.instrumentation.CModel',
'initializing', {
    initialize: function(argIdx) {
        this.argIdx = argIdx;
        this.n = 0;
        this.meanX = 0;
        this.meanY = 0;
        this.varX = 0;
        this.covarXY = 0;
        this.loss = 0;
    }
},
'analysis', {
    fit: function(args, time) {
        if (this.argIdx >= args.length) return;
        var x = this.kernel(args[this.argIdx]);
        var y = time;
        if (this.varX > 0) {
            var beta = this.covarXY / this.varX;
            var pred = 0|(this.meanY - beta* this.meanX + beta* x);
            this.loss += (this.n - 2) * Math.abs(y - pred);
        }
        this.n++;
        var meanX1 = this.meanX + (x - this.meanX) / this.n;
        var meanY1 = this.meanY + (y - this.meanY) / this.n;
        this.varX = this.varX + (x - this.meanX) * (x - meanX1);
        this.covarXY = this.covarXY + (x - this.meanX) * (y - meanY1);
        this.meanX = meanX1;
        this.meanY = meanY1;
    },
    alpha: function() {
        return this.meanY - this.meanX * this.beta();
    },
    beta: function() {
        return this.covarXY / this.varX;
    },
    _predict: function(arg) {
        return 0|(this.alpha() + this.beta() * this.kernel(arg));
    },
    predict: function(args) {
        return this._predict(args[this.argIdx]);
    }
},
'interface', {
    describe: function() {
        var log = this.loss / this.n;
        return this.name() + ":  " + (0|log) + "\n";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLinear',
'analysis', {
    kernel: function(x) {
        return x;
    }
}, 'interface', {
    name: function() {
        return "O(n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CQuadratic',
'analysis', {
    kernel: function(x) {
        return x * x;
    }
}, 'interface', {
    name: function() {
        return "O(n²)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CCubic',
'analysis', {
    kernel: function(x) {
        return x * x * x;
    }
}, 'interface', {
    name: function() {
        return "O(n³)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLogarithmic',
'analysis', {
    kernel: function(x) {
        return Math.log(x);
    }
}, 'interface', {
    name: function() {
        return "O(log n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLinearithmic',
'analysis', {
    kernel: function(x) {
        return x * Math.log(x);
    }
}, 'interface', {
    name: function() {
        return "O(n log n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CExponential',
'analysis', {
    kernel: function(x) {
        return Math.pow(2,x);
    }
}, 'interface', {
    name: function() {
        return "O(2ⁿ)";
    }
});

Object.subclass('legind.instrumentation.Profiler',
'initializing', {
    initialize: function(instructions) {
        this.timers = [];
        if (instructions) {
            this.instructions = true;
        } else {
            this.time = true;
        }
    }
},
'profiling', {
    startTimer: function(id, args) {
        var nargs = args.length;
        var fargs = new Array(nargs);
        for (var i = 0; i < nargs; i++) {
            var a =  args[i];
            var t = typeof a;
            if (t === "number") {
                fargs[i] = a;
            } else if (t === "string") {
                fargs[i] = a.length;
            } else if (a instanceof Array) {
                fargs[i] = a.length;
            } else if (a) {
                fargs[i] = 1;
            } else {
                fargs[i] = 0;
            }
        }
        var y = this.instructions ? (legind._calls + legind._ops) : Date.now();
        this.timers.push([y, id, fargs]);
    },
    stopTimer: function() {
        var last = this.timers.pop();
        if (this.time) {
            var y = Date.now() - last[0];
            if (y < 10) return;
        } else {
            var y = legind._calls + legind._ops - last[0];
        }
        this.record(last[1], y, last[2]);
    },
    record: function(id, time, args) {
        var report = this.report[id];
        report.total += time;
        var nmodels = report.cmodels.length;
        for (var i = 0; i < nmodels; i++) {
            report.cmodels[i].fit(args, time);
        }
        if (report.inv.length <= 120) {
            report.inv.push({args: args, time: time});
        }
    },
},
'reporting', {
    getReport: function() {
        return this.report;
    }
},
'running', {
    profile: function(cb) {
        legind.instrumentation.Profiler.current = this;
        if (this.instructions) {
            legind._calls = 0;
            legind._ops = 0;
        }
        cb();
        return this.getReport();
    },
    rewriteAndProfile: function(src) {
        var ast = lively.ast.Parser.parse(src, 'topLevel');
        if (!ast.isFunction) {
            ast = new lively.ast.Function([0,0], ast, []);
        }
        ast = new lively.ast.Call([0,0], ast, [])
        var prewriter = new legind.instrumentation.ProfilingTransformation();
        var rewrittenAST = prewriter.visit(ast);
        if (this.instructions) {
            var irewriter = new legind.instrumentation.InstructionCountingTransformation();
            var rewritten = irewriter.rewrite(rewrittenAST);
        } else {
            var rewritten = rewrittenAST.asJS();
        }
        console.log(rewritten);
        this.report = prewriter.templates.map(function(e) {
            return Object.extend({
                inv: [],
                total: 0,
                cmodels: e.args.map(function(arg, idx) {
                    return [
                        new legind.instrumentation.CLinear(idx),
                        new legind.instrumentation.CQuadratic(idx),
                        new legind.instrumentation.CCubic(idx),
                        new legind.instrumentation.CLogarithmic(idx),
                        new legind.instrumentation.CLinearithmic(idx),
                        new legind.instrumentation.CExponential(idx)
                    ];
                }).flatten()
            }, e);
        });
        return this.profile(eval.bind(null,rewritten));
    }
});

lively.ast.Rewriting.Transformation.subclass('legind.instrumentation.ProfilingTransformation',
'initialization', {
    initialize: function($super) {
        $super();
        this.templates = [];
    }
},
'generating', {
    addFunction: function(node) {
        this.templates.push({
            name: node.name(),
            pos: node.pos,
            args: node.args.map(function(arg) { return arg.name; })
        });
    },
    currentProfiler: function(pos) {
        var path = ["legind", "instrumentation", "Profiler", "current"];
        var result = new lively.ast.Variable(pos, path.shift());
        path.each(function(p) {
            result = new lively.ast.GetSlot(pos, new lively.ast.String(pos, p), result);
        });
        return result;
    },
    captureArgs: function(args) {
        var elements = [];
        args.each(function(arg) {
            elements.push(new lively.ast.Variable([0,0], arg.name));
        });
        return new lively.ast.ArrayLiteral([0,0], elements);
    },
    enterFunction: function(pos, args) {
        // legind.instrumentation.Profiler.current.startTimer(id, args);
        return new lively.ast.Send(pos,
            new lively.ast.String(pos,"startTimer"),
            this.currentProfiler(pos),
            [new lively.ast.Number(pos, this.templates.length-1), this.captureArgs(args)]);
    },
    exitFunction: function(pos) {
        // legind.instrumentation.Profiler.current.stopTimer();
        return new lively.ast.Send(pos,
            new lively.ast.String(pos,"stopTimer"),
            this.currentProfiler(pos),
            []);
    }
},
'visiting', {
    visitFunction: function(node) {
        this.addFunction(node);
        var enter = this.enterFunction(node.pos, node.args);
        var enterSeq = new lively.ast.Sequence(node.pos, [enter, this.visit(node.body)]);
        var error = new lively.ast.Variable(node.pos, "e");
        var noop = new lively.ast.Variable(node.pos, "undefined");
        var exit = this.exitFunction(node.pos);
        var body = new lively.ast.TryCatchFinally(node.pos, enterSeq, error, noop, exit);
        return new lively.ast.Function(body.pos,
                                       body,
                                       this.visitNodes(node.args));
    }
});

lively.ast.Rewriting.Transformation.subclass('legind.instrumentation.InstructionCountingTransformation',
'rewriting', {
    rewrite: function(ast) {
        return this.visit(ast).asJS()
            .replace("__#CALL)(", "legind._calls++,", "g")
            .replace("__#OP)(", "legind._ops++,", "g");
    }
},
'visiting', {
    visitCall: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#CALL"), [$super(node)]);
    },
    visitSend: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#CALL"), [$super(node)]);
    },
    visitBinaryOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitUnaryOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitSet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitModifyingSet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitObjPropertySet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitObjPropertySet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitPreOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitPostOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    }
});

}) // end of module
<commit_msg>report fit as normalized percentage<commit_after>module('legind.instrumentation').requires('lively.ast.Rewriting').toRun(function() {

Object.subclass('legind.instrumentation.CModel',
'initializing', {
    initialize: function(argIdx) {
        this.argIdx = argIdx;
        this.n = 0;
        this.meanX = 0;
        this.meanY = 0;
        this.varX = 0;
        this.covarXY = 0;
        this.loss = 0;
    }
},
'analysis', {
    fit: function(args, time) {
        if (this.argIdx >= args.length) return;
        var x = this.kernel(args[this.argIdx]);
        var y = time;
        if (this.varX > 0) {
            var beta = this.covarXY / this.varX;
            var pred = 0|(this.meanY - beta* this.meanX + beta* x);
            this.loss += (this.n - 2) * Math.abs(y - pred);
        }
        this.n++;
        var meanX1 = this.meanX + (x - this.meanX) / this.n;
        var meanY1 = this.meanY + (y - this.meanY) / this.n;
        this.varX = this.varX + (x - this.meanX) * (x - meanX1);
        this.covarXY = this.covarXY + (x - this.meanX) * (y - meanY1);
        this.meanX = meanX1;
        this.meanY = meanY1;
    },
    alpha: function() {
        return this.meanY - this.meanX * this.beta();
    },
    beta: function() {
        return this.covarXY / this.varX;
    },
    _predict: function(arg) {
        return 0|(this.alpha() + this.beta() * this.kernel(arg));
    },
    predict: function(args) {
        return this._predict(args[this.argIdx]);
    }
},
'interface', {
    describe: function() {
        var ploss = 0|(100 - 100 * this.loss / this.tloss);
        return this.name() + ":  " + ploss + "% (" + this.loss + ")\n";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLinear',
'analysis', {
    kernel: function(x) {
        return x;
    }
}, 'interface', {
    name: function() {
        return "O(n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CQuadratic',
'analysis', {
    kernel: function(x) {
        return x * x;
    }
}, 'interface', {
    name: function() {
        return "O(n²)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CCubic',
'analysis', {
    kernel: function(x) {
        return x * x * x;
    }
}, 'interface', {
    name: function() {
        return "O(n³)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLogarithmic',
'analysis', {
    kernel: function(x) {
        return Math.log(x);
    }
}, 'interface', {
    name: function() {
        return "O(log n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CLinearithmic',
'analysis', {
    kernel: function(x) {
        return x * Math.log(x);
    }
}, 'interface', {
    name: function() {
        return "O(n log n)";
    }
});

legind.instrumentation.CModel.subclass('legind.instrumentation.CExponential',
'analysis', {
    kernel: function(x) {
        return Math.pow(2,x);
    }
}, 'interface', {
    name: function() {
        return "O(2ⁿ)";
    }
});

Object.subclass('legind.instrumentation.Profiler',
'initializing', {
    initialize: function(instructions) {
        this.timers = [];
        if (instructions) {
            this.instructions = true;
        } else {
            this.time = true;
        }
    }
},
'profiling', {
    startTimer: function(id, args) {
        var nargs = args.length;
        var fargs = new Array(nargs);
        for (var i = 0; i < nargs; i++) {
            var a =  args[i];
            var t = typeof a;
            if (t === "number") {
                fargs[i] = a;
            } else if (t === "string") {
                fargs[i] = a.length;
            } else if (a instanceof Array) {
                fargs[i] = a.length;
            } else if (a) {
                fargs[i] = 1;
            } else {
                fargs[i] = 0;
            }
        }
        var y = this.instructions ? (legind._calls + legind._ops) : Date.now();
        this.timers.push([y, id, fargs]);
    },
    stopTimer: function() {
        var last = this.timers.pop();
        if (this.time) {
            var y = Date.now() - last[0];
            if (y < 10) return;
        } else {
            var y = legind._calls + legind._ops - last[0];
        }
        this.record(last[1], y, last[2]);
    },
    record: function(id, time, args) {
        var report = this.report[id];
        report.total += time;
        var nmodels = report.cmodels.length;
        for (var i = 0; i < nmodels; i++) {
            report.cmodels[i].fit(args, time);
        }
        if (report.inv.length <= 120) {
            report.inv.push({args: args, time: time});
        }
    },
},
'reporting', {
    getReport: function() {
        this.report.each(function(fn) {
            fn.args.each(function(arg, idx) {
                var tloss = 0;
                fn.cmodels.each(function(cmodel) {
                    if (cmodel.argIdx === idx) {
                        cmodel.loss = 0|(cmodel.loss / cmodel.n);
                        tloss += cmodel.loss;
                    }
                });
                fn.cmodels.each(function(cmodel) {
                    if (cmodel.argIdx === idx) {
                        cmodel.tloss = tloss;
                    }
                });
            });
        });
        return this.report;
    }
},
'running', {
    profile: function(cb) {
        legind.instrumentation.Profiler.current = this;
        if (this.instructions) {
            legind._calls = 0;
            legind._ops = 0;
        }
        cb();
        return this.getReport();
    },
    rewriteAndProfile: function(src) {
        var ast = lively.ast.Parser.parse(src, 'topLevel');
        if (!ast.isFunction) {
            ast = new lively.ast.Function([0,0], ast, []);
        }
        ast = new lively.ast.Call([0,0], ast, [])
        var prewriter = new legind.instrumentation.ProfilingTransformation();
        var rewrittenAST = prewriter.visit(ast);
        if (this.instructions) {
            var irewriter = new legind.instrumentation.InstructionCountingTransformation();
            var rewritten = irewriter.rewrite(rewrittenAST);
        } else {
            var rewritten = rewrittenAST.asJS();
        }
        console.log(rewritten);
        this.report = prewriter.templates.map(function(e) {
            return Object.extend({
                inv: [],
                total: 0,
                cmodels: e.args.map(function(arg, idx) {
                    return [
                        new legind.instrumentation.CLinear(idx),
                        new legind.instrumentation.CQuadratic(idx),
                        new legind.instrumentation.CCubic(idx),
                        new legind.instrumentation.CLogarithmic(idx),
                        new legind.instrumentation.CLinearithmic(idx),
                        new legind.instrumentation.CExponential(idx)
                    ];
                }).flatten()
            }, e);
        });
        return this.profile(eval.bind(null,rewritten));
    }
});

lively.ast.Rewriting.Transformation.subclass('legind.instrumentation.ProfilingTransformation',
'initialization', {
    initialize: function($super) {
        $super();
        this.templates = [];
    }
},
'generating', {
    addFunction: function(node) {
        this.templates.push({
            name: node.name(),
            pos: node.pos,
            args: node.args.map(function(arg) { return arg.name; })
        });
    },
    currentProfiler: function(pos) {
        var path = ["legind", "instrumentation", "Profiler", "current"];
        var result = new lively.ast.Variable(pos, path.shift());
        path.each(function(p) {
            result = new lively.ast.GetSlot(pos, new lively.ast.String(pos, p), result);
        });
        return result;
    },
    captureArgs: function(args) {
        var elements = [];
        args.each(function(arg) {
            elements.push(new lively.ast.Variable([0,0], arg.name));
        });
        return new lively.ast.ArrayLiteral([0,0], elements);
    },
    enterFunction: function(pos, args) {
        // legind.instrumentation.Profiler.current.startTimer(id, args);
        return new lively.ast.Send(pos,
            new lively.ast.String(pos,"startTimer"),
            this.currentProfiler(pos),
            [new lively.ast.Number(pos, this.templates.length-1), this.captureArgs(args)]);
    },
    exitFunction: function(pos) {
        // legind.instrumentation.Profiler.current.stopTimer();
        return new lively.ast.Send(pos,
            new lively.ast.String(pos,"stopTimer"),
            this.currentProfiler(pos),
            []);
    }
},
'visiting', {
    visitFunction: function(node) {
        this.addFunction(node);
        var enter = this.enterFunction(node.pos, node.args);
        var enterSeq = new lively.ast.Sequence(node.pos, [enter, this.visit(node.body)]);
        var error = new lively.ast.Variable(node.pos, "e");
        var noop = new lively.ast.Variable(node.pos, "undefined");
        var exit = this.exitFunction(node.pos);
        var body = new lively.ast.TryCatchFinally(node.pos, enterSeq, error, noop, exit);
        return new lively.ast.Function(body.pos,
                                       body,
                                       this.visitNodes(node.args));
    }
});

lively.ast.Rewriting.Transformation.subclass('legind.instrumentation.InstructionCountingTransformation',
'rewriting', {
    rewrite: function(ast) {
        return this.visit(ast).asJS()
            .replace("__#CALL)(", "legind._calls++,", "g")
            .replace("__#OP)(", "legind._ops++,", "g");
    }
},
'visiting', {
    visitCall: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#CALL"), [$super(node)]);
    },
    visitSend: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#CALL"), [$super(node)]);
    },
    visitBinaryOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitUnaryOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitSet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitModifyingSet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitObjPropertySet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitObjPropertySet: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitPreOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    },
    visitPostOp: function($super, node) {
        return new lively.ast.Call(node.pos, new lively.ast.Variable(node.pos,"__#OP"), [$super(node)]);
    }
});

}) // end of module
<|endoftext|>


<commit_before>import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
import BinWrapper from 'bin-wrapper';
import { packageConfigSync } from 'pkg-conf';

const { hugoVersion } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));

const destDir = path.join(fileURLToPath(new URL('../vendor', import.meta.url)));
const binName = process.platform === 'win32' ? 'hugo.exe' : 'hugo';

const extendedBin = (baseDownloadUrl) => new BinWrapper()
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_Linux-64bit.tar.gz`, 'linux', 'x64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'x64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'arm64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_Windows-64bit.zip`, 'win32', 'x64')
  // Fall back to the normal version on unsupported platforms
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_FreeBSD-64bit.tar.gz`, 'freebsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-32bit.tar.gz`, 'linux', 'x86')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM.tar.gz`, 'linux', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM64.tar.gz`, 'linux', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_NetBSD-64bit.tar.gz`, 'netbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_OpenBSD-64bit.tar.gz`, 'openbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-32bit.zip`, 'win32', 'x86')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM.zip`, 'win32', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM64.zip`, 'win32', 'arm64')
  .dest(destDir)
  .use(binName);

const normalBin = (baseDownloadUrl) => new BinWrapper()
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_FreeBSD-64bit.tar.gz`, 'freebsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-32bit.tar.gz`, 'linux', 'x86')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-64bit.tar.gz`, 'linux', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM.tar.gz`, 'linux', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM64.tar.gz`, 'linux', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_NetBSD-64bit.tar.gz`, 'netbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_OpenBSD-64bit.tar.gz`, 'openbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-32bit.zip`, 'win32', 'x86')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-64bit.zip`, 'win32', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM.zip`, 'win32', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM64.zip`, 'win32', 'arm64')
  .dest(destDir)
  .use(binName);

function main(projectRoot) {
  const config = packageConfigSync('hugo-bin', { cwd: projectRoot });
  const extended = (process.env.HUGO_BIN_BUILD_TAGS || process.env.npm_config_hugo_bin_build_tags || config.buildTags) === 'extended';
  const downloadRepo = (process.env.HUGO_BIN_DOWNLOAD_REPO || process.env.npm_config_hugo_bin_download_repo || config.downloadRepo || 'https://github.com');

  const baseDownloadUrl = `${downloadRepo}/gohugoio/hugo/releases/download/v${hugoVersion}/`;

  return extended ? extendedBin(baseDownloadUrl) : normalBin(baseDownloadUrl);
}

export default main;
<commit_msg>Remove no longer present binaries<commit_after>import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
import BinWrapper from 'bin-wrapper';
import { packageConfigSync } from 'pkg-conf';

const { hugoVersion } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));

const destDir = path.join(fileURLToPath(new URL('../vendor', import.meta.url)));
const binName = process.platform === 'win32' ? 'hugo.exe' : 'hugo';

const extendedBin = (baseDownloadUrl) => new BinWrapper()
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_Linux-64bit.tar.gz`, 'linux', 'x64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'x64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'arm64')
  .src(`${baseDownloadUrl}hugo_extended_${hugoVersion}_Windows-64bit.zip`, 'win32', 'x64')
  // Fall back to the normal version on unsupported platforms
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_FreeBSD-64bit.tar.gz`, 'freebsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM.tar.gz`, 'linux', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM64.tar.gz`, 'linux', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_NetBSD-64bit.tar.gz`, 'netbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_OpenBSD-64bit.tar.gz`, 'openbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM64.zip`, 'win32', 'arm64')
  .dest(destDir)
  .use(binName);

const normalBin = (baseDownloadUrl) => new BinWrapper()
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_FreeBSD-64bit.tar.gz`, 'freebsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-64bit.tar.gz`, 'linux', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM.tar.gz`, 'linux', 'arm')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Linux-ARM64.tar.gz`, 'linux', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_macOS-universal.tar.gz`, 'darwin', 'arm64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_NetBSD-64bit.tar.gz`, 'netbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_OpenBSD-64bit.tar.gz`, 'openbsd', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-64bit.zip`, 'win32', 'x64')
  .src(`${baseDownloadUrl}hugo_${hugoVersion}_Windows-ARM64.zip`, 'win32', 'arm64')
  .dest(destDir)
  .use(binName);

function main(projectRoot) {
  const config = packageConfigSync('hugo-bin', { cwd: projectRoot });
  const extended = (process.env.HUGO_BIN_BUILD_TAGS || process.env.npm_config_hugo_bin_build_tags || config.buildTags) === 'extended';
  const downloadRepo = (process.env.HUGO_BIN_DOWNLOAD_REPO || process.env.npm_config_hugo_bin_download_repo || config.downloadRepo || 'https://github.com');

  const baseDownloadUrl = `${downloadRepo}/gohugoio/hugo/releases/download/v${hugoVersion}/`;

  return extended ? extendedBin(baseDownloadUrl) : normalBin(baseDownloadUrl);
}

export default main;
<|endoftext|>