<commit_before>#!/usr/bin/env node
var fs = require("fs")
  , path = require("path")
  , docdir = path.resolve(__dirname, "..", "doc")

console.log(
  "npm-index(1) -- Index of all npm documentation\n" +
  "==============================================\n")
fs.readdir(docdir, function (er, docs) {
  if (er) throw er
  ;["../README.md"].concat(docs.filter(function (d) {
    return d !== "index.md"
         && d.charAt(0) !== "."
         && d.match(/\.md$/)
  })).forEach(function (d) {
    var doc = path.resolve(docdir, d)
      , s = fs.lstatSync(doc)
      , content = fs.readFileSync(doc, "utf8").split("\n")[0].split("--")[1]

    if (s.isSymbolicLink()) return

    console.log(d.replace(/^.*?([^\/]*)\.md$/, "## npm-$1(1)") + "\n")
    console.log(content + "\n")
  })
})
<commit_msg>Include api docs in index<commit_after>#!/usr/bin/env node
var fs = require("fs")
  , path = require("path")
  , cli = path.resolve(__dirname, "..", "doc", "cli")
  , clidocs = null
  , api = path.resolve(__dirname, "..", "doc", "api")
  , apidocs = null
  , readme = path.resolve(__dirname, "..", "README.md")

fs.readdir(cli, done("cli"))
fs.readdir(api, done("api"))

function done (which) { return function (er, docs) {
  if (er) throw er
  if (which === "api") apidocs = docs
  else clidocs = docs

  if (apidocs && clidocs) next()
}}

function filter (d) {
  return d !== "index.md"
       && d.charAt(0) !== "."
       && d.match(/\.md$/)
}

function next () {
  console.log(
    "npm-index(1) -- Index of all npm documentation\n" +
    "==============================================\n")

  apidocs = apidocs.filter(filter).map(function (d) {
    return [3, path.resolve(api, d)]
  })

  clidocs = [[1, readme]].concat(clidocs.filter(filter).map(function (d) {
    return [1, path.resolve(cli, d)]
  }))

  console.log("# Command Line Documentation")

  clidocs.forEach(writeLine)

  console.log("# API Documentation")
  apidocs.forEach(writeLine)
}

function writeLine (sd) {
  var sxn = sd[0]
    , doc = sd[1]
    , d = path.basename(doc, ".md")
    , s = fs.lstatSync(doc)

  if (s.isSymbolicLink()) return

  var content = fs.readFileSync(doc, "utf8").split("\n")[0].split("--")[1]

  console.log("## npm-%s(%d)\n", d, sxn)
  console.log(content + "\n")
}
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var getKeys = require( 'object-keys' ).shim();
var vdom2html = require( 'vdom-to-html' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var deepGet = require( '@stdlib/utils/deep-get' );
var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var namespace = require( '@stdlib/namespace' );
var docs = require( '@stdlib/repl/help' );

// VARIABLES //

var NO_HELP_TEXT = 'No help information available.';
var NAMESPACE = namespace();
var DOCS = docs();

// FUNCTIONS //

/**
* Prints help information.
*
* @private
* @param {*} alias - variable alias or value
*/
function help( alias ) {
	var txt;
	var i;

	// First check if provided an alias...
	if ( hasOwnProp( DOCS, alias ) ) {
		txt = DOCS[ alias ];
	} else {
		// Search through namespace values to see if provided a known value reference...
		for ( i = 0; i < NAMESPACE.length; i++ ) {
			if ( alias === NAMESPACE[ i ].value ) {
				if ( hasOwnProp( DOCS, NAMESPACE[ i ].alias ) ) {
					txt = DOCS[ NAMESPACE[ i ].alias ];
				}
				break;
			}
		}
		// If still unable to resolve help info, inform the user that no info is available...
		if ( txt === void 0 ) {
			txt = NO_HELP_TEXT;
		}
	}
	console.log( txt ); // eslint-disable-line no-console
} // end FUNCTION help()

/**
* Prints the list of namespace aliases.
*
* @private
*/
function ns() {
	var i;
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		console.log( NAMESPACE[ i ].alias ); // eslint-disable-line no-console
	}
} // end FUNCTION ns()

// MAIN //

/**
* Extends the browser global namespace.
*
* @private
*/
function main() {
	var paths;
	var parts;
	var keys;
	var tmp;
	var key;
	var o;
	var i;
	var j;
	var k;

	// Create an object tree from value aliases...
	tmp = {
		'help': help,
		'_help': help, // Firefox devtools already aliases `help` (and `?`) to a read-only value :(
		'require': require,
		'namespace': ns
	};
	paths = [];
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		o = tmp;

		// Get the alias of the value to be added to the global context:
		key = NAMESPACE[ i ].alias;

		// Cache the alias path:
		paths.push( key );

		// An alias may be nested (e.g., `a.b.c`); if so, we need to recursively generate parent sub-trees...
		parts = key.split( '.' );
		for ( j = 0; j < parts.length-1; j++ ) {
			k = parts[ j ];
			if ( !hasOwnProp( o, k ) ) {
				o[ k ] = {};
			}
			o = o[ k ];
		}
		k = parts[ j ];

		// Attempt to add the value to the tree (checking for collisions):
		if ( hasOwnProp( o, k ) ) {
			throw new Error( 'invalid operation. Alias already exists in the global context. Alias: `'+key+'`. Value: `'+deepGet( tmp, key )+'`.' );
		} else {
			o[ k ] = NAMESPACE[ i ].value;
		}
	}
	// Walk the context tree and set each nested path to read-only...
	for ( i = 0; i < paths.length; i++ ) {
		parts = paths[ i ].split( '.' );
		if ( parts.length > 1 ) {
			o = tmp;
			for ( j = 0; j < parts.length; j++ ) {
				k = parts[ j ];
				setReadOnly( o, k, o[ k ] );
				o = o[ k ];
			}
		}
	}
	// Extend the global context...
	keys = getKeys( tmp );
	for ( i = 0; i < keys.length; i++ ) {
		key = keys[ i ];
		setReadOnly( global, key, tmp[ key ] );
	}
	// Include any additional third party libraries...
	setReadOnly( global, 'vdom2html', vdom2html );
} // end FUNCTION main()

main();
<commit_msg>Add support for resolving a pkg from an alias in browser REPL<commit_after>'use strict';

// MODULES //

var getKeys = require( 'object-keys' ).shim();
var vdom2html = require( 'vdom-to-html' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var deepGet = require( '@stdlib/utils/deep-get' );
var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var namespace = require( '@stdlib/namespace' );
var docs = require( '@stdlib/repl/help' );

// VARIABLES //

var NO_HELP_TEXT = 'No help information available.';
var NO_PKG_TEXT = 'Unrecognized alias.';
var NAMESPACE = namespace();
var DOCS = docs();

// FUNCTIONS //

/**
* Prints help information.
*
* @private
* @param {*} alias - variable alias or value
*/
function help( alias ) {
	var txt;
	var i;

	// First check if provided an alias...
	if ( hasOwnProp( DOCS, alias ) ) {
		txt = DOCS[ alias ];
	} else {
		// Search through namespace values to see if provided a known value reference...
		for ( i = 0; i < NAMESPACE.length; i++ ) {
			if ( alias === NAMESPACE[ i ].value ) {
				if ( hasOwnProp( DOCS, NAMESPACE[ i ].alias ) ) {
					txt = DOCS[ NAMESPACE[ i ].alias ];
				}
				break;
			}
		}
		// If still unable to resolve help info, inform the user that no info is available...
		if ( txt === void 0 ) {
			txt = NO_HELP_TEXT;
		}
	}
	console.log( txt ); // eslint-disable-line no-console
} // end FUNCTION help()

/**
* Prints the list of namespace aliases.
*
* @private
*/
function ns() {
	var i;
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		console.log( NAMESPACE[ i ].alias ); // eslint-disable-line no-console
	}
} // end FUNCTION ns()

/**
* Prints the package name corresponding to a provided alias.
*
* @private
* @param {*} alias - variable alias or value
*/
function alias2pkg( alias ) {
	var txt;
	var i;

	// Check if provided an alias or a known value reference...
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		if (
			alias === NAMESPACE[ i ].alias ||
			alias === NAMESPACE[ i ].value
		) {
			txt = NAMESPACE[ i ].path;
			break;
		}
	}
	if ( txt === void 0 ) {
		txt = NO_PKG_TEXT;
	}
	console.log( txt ); // eslint-disable-line no-console
} // end FUNCTION alias2pkg()

// MAIN //

/**
* Extends the browser global namespace.
*
* @private
*/
function main() {
	var paths;
	var parts;
	var keys;
	var tmp;
	var key;
	var o;
	var i;
	var j;
	var k;

	// Create an object tree from value aliases...
	tmp = {
		'help': help,
		'_help': help, // Firefox devtools already aliases `help` (and `?`) to a read-only value :(
		'require': require,
		'namespace': ns,
		'alias2pkg': alias2pkg
	};
	paths = [];
	for ( i = 0; i < NAMESPACE.length; i++ ) {
		o = tmp;

		// Get the alias of the value to be added to the global context:
		key = NAMESPACE[ i ].alias;

		// Cache the alias path:
		paths.push( key );

		// An alias may be nested (e.g., `a.b.c`); if so, we need to recursively generate parent sub-trees...
		parts = key.split( '.' );
		for ( j = 0; j < parts.length-1; j++ ) {
			k = parts[ j ];
			if ( !hasOwnProp( o, k ) ) {
				o[ k ] = {};
			}
			o = o[ k ];
		}
		k = parts[ j ];

		// Attempt to add the value to the tree (checking for collisions):
		if ( hasOwnProp( o, k ) ) {
			throw new Error( 'invalid operation. Alias already exists in the global context. Alias: `'+key+'`. Value: `'+deepGet( tmp, key )+'`.' );
		} else {
			o[ k ] = NAMESPACE[ i ].value;
		}
	}
	// Walk the context tree and set each nested path to read-only...
	for ( i = 0; i < paths.length; i++ ) {
		parts = paths[ i ].split( '.' );
		if ( parts.length > 1 ) {
			o = tmp;
			for ( j = 0; j < parts.length; j++ ) {
				k = parts[ j ];
				setReadOnly( o, k, o[ k ] );
				o = o[ k ];
			}
		}
	}
	// Extend the global context...
	keys = getKeys( tmp );
	for ( i = 0; i < keys.length; i++ ) {
		key = keys[ i ];
		setReadOnly( global, key, tmp[ key ] );
	}
	// Include any additional third party libraries...
	setReadOnly( global, 'vdom2html', vdom2html );
} // end FUNCTION main()

main();
<|endoftext|>


<commit_before>var Alloy = require('alloy'),
	_ = Alloy._,
	Backbone = Alloy.Backbone;

var Cloud = (function() {

	// constructor
	var cls = function(config) {
		_.extend(this, {
			/**
			 * @property {Ti.Network.HttpClient} httpClient The internal httpClient used to perform the request
			 */
			httpClient: null,

			onSuccess: null,
			onError: null,

			/**
			 * Constructor
			 *
			 * @param {Object} config Class configuration
			 */
			construct: function(config) {
				this.onSuccess = config.success;
				this.onError = config.error;

				var clientConfig = {
					onload: _.partial(onSuccess, this),
					onerror: _.partial(onError, this),
					ondatastream: config.progress,
					onsendstream: config.progress,
					onreadystatechange: config.stateChange,
					timeout: config.timeout || 10000
				};

				// Create http client
				this.httpClient = Ti.Network.createHTTPClient(clientConfig);

				// Set headers
				for (var key in config.headers) {
					this.httpClient.setRequestHeader(key, config.headers[key]);
				}

				// make sure we have a data object
				config.data = config.data || {};

				// Prepare the data (if required)
				var url = config.url,
					method = config.method || 'GET',
					data, query;

				if (method == 'GET' || method == 'DELETE') {
					if (query = toQueryString(config.data))
						url = url + (url.indexOf('?') > 0 ? '&' : '?') + query;
				} else
					data = config.data;

				// Add base Url
				url = Alloy.CFG.baseUrl + url;

				Ti.API.info(method + ': ' + url);
				// Ti.API.info(data);

				// Open connection
				this.httpClient.open(method, url);

				this.httpClient.send(data);
			},

			/**
			 * Remove this object from memory gracefully
			 */
			destruct: function() {
				if (this.httpClient) {
					this.httpClient.abort();
					this.httpClient = null;
				}
			}
		});

		// Call construct on object initialization
		this.construct(config);
	};

	function onSuccess(req, result) {
		var response;

		if (result.success) {
			try {
				response = JSON.parse(this.responseText);
			} catch (e) {
				Ti.API.error('Tried to parse response, but it was not valid json.');
				Ti.API.error(this.responseText);
				response = this.responseText;
			}
		}

		// Call callback
		if (req.onSuccess)
			req.onSuccess(response);
	}

	function onError(req, result) {
		var response;

		try {
			response = JSON.parse(this.responseText);
		} catch (e) {
			Ti.API.error('Tried to parse response, but it was not valid json.');
			Ti.API.error(this.responseText);
			response = this.responseText;
		}

		Ti.API.info(response);

		// Call callback
		if (req.onError)
			req.onError(response);
	}

	/**
	 * Converts the supplied object into a query string
	 * @private
	 *
	 * @param {Object} data The object to convert
	 * @return {String} The generated query string
	 */
	function toQueryString(data) {
		var query = [],
			queryString = '',
			key;

		if (data) {
			for (key in data) {
				if (data.hasOwnProperty(key))
					query.push(Ti.Network.encodeURIComponent(key) + '=' + Ti.Network.encodeURIComponent(data[key]));
			}

			if (query.length)
				queryString = query.join('&');
		}

		return queryString;
	}

	return cls;
})();

module.exports = Cloud;
<commit_msg>Cloud: Only set headers after opening connection<commit_after>var Alloy = require('alloy'),
	_ = Alloy._,
	Backbone = Alloy.Backbone;

var Cloud = (function() {

	// constructor
	var cls = function(config) {
		_.extend(this, {
			/**
			 * @property {Ti.Network.HttpClient} httpClient The internal httpClient used to perform the request
			 */
			httpClient: null,

			onSuccess: null,
			onError: null,

			/**
			 * Constructor
			 *
			 * @param {Object} config Class configuration
			 */
			construct: function(config) {
				this.onSuccess = config.success;
				this.onError = config.error;

				var clientConfig = {
					onload: _.partial(onSuccess, this),
					onerror: _.partial(onError, this),
					ondatastream: config.progress,
					onsendstream: config.progress,
					onreadystatechange: config.stateChange,
					timeout: config.timeout || 10000
				};

				// Create http client
				this.httpClient = Ti.Network.createHTTPClient(clientConfig);

				// make sure we have a data object
				config.data = config.data || {};

				// Prepare the data (if required)
				var url = config.url,
					method = config.method || 'GET',
					data, query;

				if (method == 'GET' || method == 'DELETE') {
					if (query = toQueryString(config.data))
						url = url + (url.indexOf('?') > 0 ? '&' : '?') + query;
				} else
					data = config.data;

				// Add base Url
				url = Alloy.CFG.baseUrl + url;

				Ti.API.info(method + ': ' + url);
				// Ti.API.info(data);

				// Open connection
				this.httpClient.open(method, url);

				// Set headers after opening connection
				for (var key in config.headers) {
					this.httpClient.setRequestHeader(key, config.headers[key]);
				}

				Ti.API.info(config.headers);

				this.httpClient.send(data);
			},

			/**
			 * Remove this object from memory gracefully
			 */
			destruct: function() {
				if (this.httpClient) {
					this.httpClient.abort();
					this.httpClient = null;
				}
			}
		});

		// Call construct on object initialization
		this.construct(config);
	};

	function onSuccess(req, result) {
		var response;

		if (result.success) {
			try {
				response = JSON.parse(this.responseText);
			} catch (e) {
				Ti.API.error('Tried to parse response, but it was not valid json.');
				Ti.API.error(this.responseText);
				response = this.responseText;
			}
		}

		// Call callback
		if (req.onSuccess)
			req.onSuccess(response);
	}

	function onError(req, result) {
		var response;

		try {
			response = JSON.parse(this.responseText);
		} catch (e) {
			Ti.API.error('Tried to parse response, but it was not valid json.');
			Ti.API.error(this.responseText);
			response = this.responseText;
		}

		Ti.API.info(response);

		// Call callback
		if (req.onError)
			req.onError(response);
	}

	/**
	 * Converts the supplied object into a query string
	 * @private
	 *
	 * @param {Object} data The object to convert
	 * @return {String} The generated query string
	 */
	function toQueryString(data) {
		var query = [],
			queryString = '',
			key;

		if (data) {
			for (key in data) {
				if (data.hasOwnProperty(key))
					query.push(Ti.Network.encodeURIComponent(key) + '=' + Ti.Network.encodeURIComponent(data[key]));
			}

			if (query.length)
				queryString = query.join('&');
		}

		return queryString;
	}

	return cls;
})();

module.exports = Cloud;
<|endoftext|>


<commit_before>// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

let webview = document.getElementById('webcontent');
let body = document.getElementsByTagName('body')[0];

const {screen, remote} = require('electron');
const {Menu, MenuItem} = remote;
const _ = require('lodash');

const globalSettings = remote.getCurrentWindow().globalSettings;
const displaySettings = remote.getCurrentWindow().display;
console.log('globalSettings', globalSettings, 'displaySettings', displaySettings);

window.addEventListener('load', function() {
  displayInfoPage(`Loading..`, `Please wait while the page is initially loaded.`);
  setDefaultPosition();
  webview.src = displaySettings.url;
});

webview.addEventListener('did-fail-load',   function(event, errorCode, errorDescription, validatedURL, isMainFrame) {
  console.log('did-fail-load', {
    event:event,
    errorCode:errorCode,
    errorDescription:errorDescription,
    validatedURL:validatedURL,
    isMainFrame:isMainFrame});

  lastHttpResponse = null;
  displayInfoPage(`Error`, `Page failed to load: ${errorDescription} (${errorCode})`);

  setTimeout(function() {
    webview.src = displaySettings.url;
  }, globalSettings.failureRetryTime);
});

webview.addEventListener('did-get-response-details', function(details) {
  console.log('did-get-response-details', details);

  hideInfo();

  if (details.httpResponseCode < 200 || details.httpResponseCode >= 300)
  {
    console.log(`last response code is ${details.httpResponseCode}, re-loading URL ${displaySettings.url}`);
    // TODO: display overlay message

    setTimeout(function() {
      webview.src = displaySettings.url;
    }, globalSettings.nonSuccessRetryTime);
  }
});
webview.addEventListener('crashed', function() {
  console.log('crashed');
});

const menu = Menu.buildFromTemplate([
  {
    label: 'Reload',
    accelerator: 'CmdOrCtrl+R',
    click (item, focusedWindow) {
      if (focusedWindow) focusedWindow.reload()
    }
  },
  {type: 'separator'},
  {
    label: "Move to display",
    submenu: _.map(screen.getAllDisplays(), function(display,index) {
      return {
        label: `Display ${index+1}`,
        click: function() { moveToDisplay(index) },
      };
    })
  },
  {
    label: 'Toggle Fullscreen',
    accelerator: 'F11',
    click (item, focusedWindow) {
      focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
    }
  },
  {
    label: 'Reset to configured position',
    click (item, focusedWindow) {
      setDefaultPosition();
    }
  },
  {
    label: 'Toggle Developer Tools',
    accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
    click (item, focusedWindow) {
      if (focusedWindow) focusedWindow.webContents.toggleDevTools()
    }
  },
  {type: 'separator'},
  {
    label:'Exit',
    accelerator: 'Alt+F4',
    role:'close'
  }
]);

window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  menu.popup(remote.getCurrentWindow())
}, false)

function displayInfoPage(header, details)
{
    body.className = 'info';
    document.getElementById('infoTitle').innerHTML = header;
    document.getElementById('infoText').innerHTML = details;
}
function hideInfo()
{
    body.className = '';
}

function moveToDisplay(displayIndex)
{
  let displays = screen.getAllDisplays();
  let thisWindow = remote.getCurrentWindow();
  thisWindow.setPosition(displays[displayIndex].workArea.x, displays[displayIndex].workArea.y);
}

function setDefaultPosition() {
  let displays = screen.getAllDisplays();
  let thisWindow = remote.getCurrentWindow();

  let displayIndex = displaySettings.screen - 1;
  let displayBasePosition = [displays[displayIndex].workArea.x, displays[displayIndex].workArea.y];

  if (displaySettings.position == 'fullscreen' || displaySettings.size == 'fullscreen') {
    thisWindow.setPosition(displayBasePosition[0], displayBasePosition[1]);
    thisWindow.setFullScreen(true);
  } else {
    thisWindow.setFullScreen(false);

    thisWindow.setSize(displaySettings.size[0], displaySettings.size[1]);

    let targetX = displayBasePosition[0] + displaySettings.position[0];
    let targetY = displayBasePosition[1] + displaySettings.position[1];
    // todo check within bounds
    thisWindow.setPosition(targetX,targetY);

  }

}<commit_msg>Improve handling of moving fullscreen windows<commit_after>// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.

let webview = document.getElementById('webcontent');
let body = document.getElementsByTagName('body')[0];

const {screen, remote} = require('electron');
const {Menu, MenuItem} = remote;
const _ = require('lodash');

const globalSettings = remote.getCurrentWindow().globalSettings;
const displaySettings = remote.getCurrentWindow().display;
console.log('globalSettings', globalSettings, 'displaySettings', displaySettings);

window.addEventListener('load', function() {
  displayInfoPage(`Loading..`, `Please wait while the page is initially loaded.`);
  setDefaultPosition();
  webview.src = displaySettings.url;
});

webview.addEventListener('did-fail-load',   function(event, errorCode, errorDescription, validatedURL, isMainFrame) {
  console.log('did-fail-load', {
    event:event,
    errorCode:errorCode,
    errorDescription:errorDescription,
    validatedURL:validatedURL,
    isMainFrame:isMainFrame});

  lastHttpResponse = null;
  displayInfoPage(`Error`, `Page failed to load: ${errorDescription} (${errorCode})`);

  setTimeout(function() {
    webview.src = displaySettings.url;
  }, globalSettings.failureRetryTime);
});

webview.addEventListener('did-get-response-details', function(details) {
  console.log('did-get-response-details', details);

  hideInfo();

  if (details.httpResponseCode < 200 || details.httpResponseCode >= 300)
  {
    console.log(`last response code is ${details.httpResponseCode}, re-loading URL ${displaySettings.url}`);
    // TODO: display overlay message

    setTimeout(function() {
      webview.src = displaySettings.url;
    }, globalSettings.nonSuccessRetryTime);
  }
});
webview.addEventListener('crashed', function() {
  console.log('crashed');
});

const menu = Menu.buildFromTemplate([
  {
    label: 'Reload',
    accelerator: 'CmdOrCtrl+R',
    click (item, focusedWindow) {
      if (focusedWindow) focusedWindow.reload()
    }
  },
  {type: 'separator'},
  {
    label: "Move to display",
    submenu: _.map(screen.getAllDisplays(), function(display,index) {
      return {
        label: `Display ${index+1}`,
        click: function() { moveToDisplay(index) },
      };
    })
  },
  {
    label: 'Toggle Fullscreen',
    accelerator: 'F11',
    click (item, focusedWindow) {
      focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
    }
  },
  {
    label: 'Reset to configured position',
    click (item, focusedWindow) {
      setDefaultPosition();
    }
  },
  {
    label: 'Toggle Developer Tools',
    accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
    click (item, focusedWindow) {
      if (focusedWindow) focusedWindow.webContents.toggleDevTools()
    }
  },
  {type: 'separator'},
  {
    label:'Exit',
    accelerator: 'Alt+F4',
    role:'close'
  }
]);

window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  menu.popup(remote.getCurrentWindow())
}, false)

function displayInfoPage(header, details)
{
    body.className = 'info';
    document.getElementById('infoTitle').innerHTML = header;
    document.getElementById('infoText').innerHTML = details;
}
function hideInfo()
{
    body.className = '';
}

function moveToDisplay(displayIndex)
{
  setPosition(displayIndex, null, null);
}

function setDefaultPosition() {
  setPosition(displaySettings.screen - 1, displaySettings.position, displaySettings.size);
}

function setPosition(displayIndex, position, size) {
  let displays = screen.getAllDisplays();
  let thisWindow = remote.getCurrentWindow();

  let displayBasePosition = [displays[displayIndex].workArea.x, displays[displayIndex].workArea.y];
  let currentPosition = thisWindow.getPosition();

  // preserve fullscreen
  if (size == null && thisWindow.isFullScreen()) {
    size = 'fullscreen';
  }
  // preserve offset on display, if not specified
  if (position == null) {
    // get current offset on current display
    let currentDisplay = screen.getDisplayNearestPoint({x:currentPosition[0], y:currentPosition[1]});
    position = [currentPosition[0] - currentDisplay.workArea.x, currentPosition[1] - currentDisplay.workArea.y];
  }

  if (position == 'fullscreen' || size == 'fullscreen') {
    // if not currently fullscreen, or x or y position is wrong (wrong display), move to proper screen
    if (!thisWindow.isFullScreen() || (currentPosition[0] != displayBasePosition[0]) || (currentPosition[1] != displayBasePosition[1])) {
      thisWindow.setFullScreen(false); // must be non-fullscreen to move screens
      thisWindow.setPosition(displayBasePosition[0], displayBasePosition[1]);
      thisWindow.setFullScreen(true);
    }
  } else {
    thisWindow.setFullScreen(false);

    if (size != null) thisWindow.setSize(size[0], size[1]);

    let targetX = displayBasePosition[0] + position[0];
    let targetY = displayBasePosition[1] + position[1];
    // todo check within bounds of display
    thisWindow.setPosition(targetX,targetY);

  }

}<|endoftext|>


<commit_before>/*
---

name: Color
description: Class to create and manipulate colors. Includes HSB «-» RGB «-» HEX conversions.
provides: Color

...
*/

(function(){

this.Color = function(color, type){

	if (color.isColor){

		this.red = color.red;
		this.green = color.green;
		this.blue = color.blue;
		this.alpha = color.alpha;

	} else {

		switch (typeof color){
			case 'string': if (!type) type = (type = color.match(/^rgb|^hsb/)) ? type[0] : 'hex'; break;
			case 'object': type = type || 'rgb'; color = color.toString(); break;
			case 'number': type = 'hex'; color = color.toString(16); break;
		}

		color = Color['parse' + type.toUpperCase()](color);
		this.red = color[0];
		this.green = color[1];
		this.blue = color[2];
		this.alpha = color[3];
	}

	this.isColor = true;

};

var limit = function(number, min, max){
	return Math.min(max, Math.max(min, number));
};

var listMatch = /([-.\d]+)\s*,\s*([-.\d]+)\s*,\s*([-.\d]+)\s*,?\s*([-.\d]*)/;
var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;

Color.parseRGB = function(color){
	return color.match(listMatch).slice(1).map(function(bit, i){
		return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
	});
};

Color.parseHEX = function(color){
	if (color.length == 1) color = color + color + color;
	return color.match(hexMatch).slice(1).map(function(bit, i){
		if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
		return parseInt((bit.length == 1) ? bit + bit : bit, 16);
	});
};

Color.parseHSB = function(color){
	var hsb = color.match(listMatch).slice(1).map(function(bit, i){
		if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
		else if (i < 3) return limit(Math.round(bit), 0, 100);
		else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
	});

	var a = hsb[3];
	var br = Math.round(hsb[2] / 100 * 255);
	if (hsb[1] == 0) return [br, br, br, a];

	var hue = hsb[0];
	var f = hue % 60;
	var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
	var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
	var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);

	switch (Math.floor(hue / 60)){
		case 0: return [br, t, p, a];
		case 1: return [q, br, p, a];
		case 2: return [p, br, t, a];
		case 3: return [p, q, br, a];
		case 4: return [t, p, br, a];
		default: return [br, p, q, a];
	}
};

var toString = function(type, array){
	if (array[3] != 1) type += 'a';
	else array.pop();
	return type + '(' + array.join(', ') + ')';
};

Color.prototype = {

	toHSB: function(array){
		var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;

		var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
		var hue = 0, saturation = (max != 0) ? delta / max : 0, brightness = max / 255;
		if (saturation){
			var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
			hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
			if ((hue /= 6) < 0) hue++;
		}

		var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];

		return (array) ? hsb : toString('hsb', hsb);
	},

	toHEX: function(array){

		var a = this.alpha;
		var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;

		var hex = [this.red, this.green, this.blue].map(function(bit){
			bit = bit.toString(16);
			return (bit.length == 1) ? '0' + bit : bit;
		});

		return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
	},

	toRGB: function(array){
		var rgb = [this.red, this.green, this.blue, this.alpha];
		return (array) ? rgb : toString('rgb', rgb);
	}

};

Color.prototype.toString = Color.prototype.toRGB;

Color.hex = function(hex){
	return new Color(hex, 'hex');
};

if (this.hex == null) this.hex = Color.hex;

Color.hsb = function(h, s, b, a){
	return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
};

if (this.hsb == null) this.hsb = Color.hsb;

Color.rgb = function(r, g, b, a){
	return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
};

if (this.rgb == null) this.rgb = Color.rgb;

}).call(typeof exports != 'undefined' ? exports : this);
<commit_msg> - thank you Christoph Pojer<commit_after>/*
---

name: Color
description: Class to create and manipulate colors. Includes HSB «-» RGB «-» HEX conversions.
provides: Color

...
*/

(function(){

var Color = this.Color = function(color, type){

	if (color.isColor){

		this.red = color.red;
		this.green = color.green;
		this.blue = color.blue;
		this.alpha = color.alpha;

	} else {

		switch (typeof color){
			case 'string': if (!type) type = (type = color.match(/^rgb|^hsb/)) ? type[0] : 'hex'; break;
			case 'object': type = type || 'rgb'; color = color.toString(); break;
			case 'number': type = 'hex'; color = color.toString(16); break;
		}

		color = Color['parse' + type.toUpperCase()](color);
		this.red = color[0];
		this.green = color[1];
		this.blue = color[2];
		this.alpha = color[3];
	}

	this.isColor = true;

};

var limit = function(number, min, max){
	return Math.min(max, Math.max(min, number));
};

var listMatch = /([-.\d]+)\s*,\s*([-.\d]+)\s*,\s*([-.\d]+)\s*,?\s*([-.\d]*)/;
var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;

Color.parseRGB = function(color){
	return color.match(listMatch).slice(1).map(function(bit, i){
		return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
	});
};

Color.parseHEX = function(color){
	if (color.length == 1) color = color + color + color;
	return color.match(hexMatch).slice(1).map(function(bit, i){
		if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
		return parseInt((bit.length == 1) ? bit + bit : bit, 16);
	});
};

Color.parseHSB = function(color){
	var hsb = color.match(listMatch).slice(1).map(function(bit, i){
		if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
		else if (i < 3) return limit(Math.round(bit), 0, 100);
		else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
	});

	var a = hsb[3];
	var br = Math.round(hsb[2] / 100 * 255);
	if (hsb[1] == 0) return [br, br, br, a];

	var hue = hsb[0];
	var f = hue % 60;
	var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
	var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
	var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);

	switch (Math.floor(hue / 60)){
		case 0: return [br, t, p, a];
		case 1: return [q, br, p, a];
		case 2: return [p, br, t, a];
		case 3: return [p, q, br, a];
		case 4: return [t, p, br, a];
		default: return [br, p, q, a];
	}
};

var toString = function(type, array){
	if (array[3] != 1) type += 'a';
	else array.pop();
	return type + '(' + array.join(', ') + ')';
};

Color.prototype = {

	toHSB: function(array){
		var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;

		var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
		var hue = 0, saturation = (max != 0) ? delta / max : 0, brightness = max / 255;
		if (saturation){
			var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
			hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
			if ((hue /= 6) < 0) hue++;
		}

		var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];

		return (array) ? hsb : toString('hsb', hsb);
	},

	toHEX: function(array){

		var a = this.alpha;
		var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;

		var hex = [this.red, this.green, this.blue].map(function(bit){
			bit = bit.toString(16);
			return (bit.length == 1) ? '0' + bit : bit;
		});

		return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
	},

	toRGB: function(array){
		var rgb = [this.red, this.green, this.blue, this.alpha];
		return (array) ? rgb : toString('rgb', rgb);
	}

};

Color.prototype.toString = Color.prototype.toRGB;

Color.hex = function(hex){
	return new Color(hex, 'hex');
};

if (this.hex == null) this.hex = Color.hex;

Color.hsb = function(h, s, b, a){
	return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
};

if (this.hsb == null) this.hsb = Color.hsb;

Color.rgb = function(r, g, b, a){
	return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
};

if (this.rgb == null) this.rgb = Color.rgb;

}).call(typeof exports != 'undefined' ? exports : this);
<|endoftext|>


<commit_before>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.setupTrafficLightOpensDiffDialogHandlers = function(nodes, title) {
	nodes.click(function() {
	  var id = $(this).data('id');
	  var avatarName = $(this).data('avatar-name');
	  var wasTag = $(this).data('was-tag');
	  var nowTag = $(this).data('now-tag');
	  var maxTag = $(this).data('max-tag');
	  cd.dialog_diff(title, id, avatarName, wasTag, nowTag, maxTag);
	});
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.dialog_diff = function(title, id, avatarName, wasTag, nowTag, maxTag) {

  	var minTag = 0;
    var tagGap = nowTag - wasTag;

    var makeDiffInfo = function() {
	  return '' +
	    '
' +
		  '
' +
		    '' +
			  '
' +
			  '
' +
		    '	' +
			'' +
			  '<input type="text" id="was_tag_number" value="' + wasTag + '" />' +
			'	' +
			'' +
			  '←' +
			'	' +
			'' +
			  '
' +
			    tagGap +
			  '
' +
			'	' +
			'' +
			  '→' +
			'	' +
			'' +
			  '<input type="text" id="now_tag_number" value="' + nowTag + '" />' +
			'	' +
		    '' +
			  '
' +
			  '
' +
		    '	' +
		  '
' +
		'
';
    };

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

    var makeDiffDiv = function()  {
      var div = $('
', {
        'id': 'diff_dialog'
      });
      var table = $('
');
      table.append(
        "
" +
          "" +

		    "
" +
			  "
" +
				"" +
			      makeDiffInfo() +
			    "	" +
			  "
" +

			  "
" +
				"" +
				  cd.makeNavigateButtons(avatarName) +
				"	" +
			  "
" +

			  "
" +
				"" +
				  "
" +
				  "
" +
				"	" +
			  "
" +

			"
" +

          "	" +
          "" +
            "
" +
		    "
" +
          "	" +
	    "
");

      div.append(table);
      return div;
    };

    var diffDiv = makeDiffDiv();

    //- - - - - - - - - - - - - - - - - - - - - - - - - -
    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var wasTagNumber = $('#was_tag_number', diffDiv);
	var tagGapNumber = $('#tag_gap_number', diffDiv);
	var nowTagNumber = $('#now_tag_number', diffDiv);

	var wasTrafficLight = $('#was_traffic_light', diffDiv);
	var nowTrafficLight = $('#now_traffic_light', diffDiv);

	var firstButton = $('#first_button', diffDiv);
	var prevButton  = $('#prev_button',  diffDiv);
	var nextButton  = $('#next_button',  diffDiv);
	var lastButton  = $('#last_button',  diffDiv);

    var resetNavigateButtonHandlers = function() {

	  var toolTip = function(was, now) {
		if (was !== now) {
		  return 'Show diff of ' + was + ' <-> ' + now;
		} else {
		  return 'Show ' + was;
		}
	  };

	  var showDiff = function(was,now) {
		wasTag = was;
		nowTag = now;
		tagGap = now - was;
		refresh();
	  };

	  var tagEdit = function(event) {
		if (event.keyCode === $.ui.keyCode.ENTER) {
		  var newWasTag = parseInt(wasTagNumber.val(), 10);
		  var newNowTag = parseInt(nowTagNumber.val(), 10);
		  if (isNaN(newWasTag) || newWasTag < minTag ||
				isNaN(newNowTag) || newNowTag > maxTag ||
				  newWasTag > newNowTag) {
			wasTagNumber.val(wasTag);
			nowTagNumber.val(nowTag);
		  } else {
			showDiff(newWasTag, newNowTag);
		  }
		}
	  };

	  var refreshNavigationHandlers = function(off, button, from, to) {
		button.attr('disabled', off);
		if (!off) {
		  button.unbind()
			.click(function() { showDiff(from, to); })
			.attr('title', toolTip(from, to));
		}
	  };

	  // The wasTagNumber and nowTagNumber may have been edited since the
	  // refresh but before a navigation button is pressed. However, the
	  // navigation buttons do _not_ look at the current state of the
	  // wasTagNumber/nowTagNumbers, but use the values set on refresh.
	  // This is the simplest way to ensure the navigation buttons are
	  // not incorrectly enabled/disabled.
	  refreshNavigationHandlers(minTag >= wasTag, firstButton, minTag, minTag+tagGap);
	  refreshNavigationHandlers(minTag >= wasTag, prevButton, wasTag-1, nowTag-1);
	  refreshNavigationHandlers(nowTag >= maxTag, nextButton, wasTag+1, nowTag+1);
	  refreshNavigationHandlers(nowTag >= maxTag, lastButton, maxTag-tagGap, maxTag);

	  wasTagNumber.unbind().keyup(function(event) { tagEdit(event); });
	  nowTagNumber.unbind().keyup(function(event) { tagEdit(event); });
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

  	var makeTrafficLight = function(trafficLight) {
      var filename = 'traffic_light_' + trafficLight.colour;
      return '' +
		"";
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffContent = $('#diff_content', diffDiv);

    var makeDiffContent = function(diffs) {
	  var span = $('');
	  $.each(diffs, function(_, diff) {
		var divHolder = $('
', {
		  id: diff.filename + '_diff_div',
		  'class': 'filename_div'
		});
		var div = $('
', {
		  id: 'diff_file_content_for_' + diff.filename,
		  'class': 'diff_sheet'
		});
		div.html(diff.content);
		divHolder.append(div);
		span.append(divHolder);
	  });
	  return span;
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var buildDiffFilenameHandlers = function(diffs) {
	  // Builds the diff filename click handlers for a given kata-id,
	  // given animal-name, and given traffic-light was/now numbers.
	  // Clicking on the filename brings it into view by hiding the
	  // previously selected file and showing the selected one.
	  //
	  // The first time the filename for a file with one or more
	  // diff-sections is clicked its diff-section is scrolled into view.
	  //
	  // Subsequent times if you click on the filename you will _not_ get
	  // an autoscroll. This is so that the scrollPos of a diff that has
	  // been manually scrolled is retained.
	  //
	  // However, if filename X is open and you reclick on filename X
	  // then you _will_ get an autoscroll to the _next_ diff-section in that
	  // diff (which will cycle round).

	  var previousFilenameNode;
	  var alreadyOpened = [ ];
	  var getFilename = function(node) {
		return $.trim(node.text());
	  };

	  var diffFileContentFor = function(filename) {
		return cd.id('diff_file_content_for_' + filename);
	  };

	  var diffFileDiv = function(filename) {
		return cd.id(filename + '_diff_div');
	  };

	  var loadFrom = function(filename, filenameNode, id, sectionCount) {

		var diffSheet = diffFileContentFor(filename);
		var sectionIndex = 0;

		if (sectionCount > 0) {
			filenameNode.attr('title', 'Auto-scroll through diffs');
		}

		return function() {
		  var reselected =
			previousFilenameNode !== undefined && getFilename(previousFilenameNode) === filename;

		  var allLineCountButtons = $('.diff-deleted-line-count, .diff-added-line-count');
		  var off = { 'disabled':true, 'title':'' };
		  var disableAllLineCountButtons = function() {
			allLineCountButtons.attr(off);
		  };
		  var tr = filenameNode.closest('tr');
		  disableAllLineCountButtons();
		  tr.find('.diff-deleted-line-count')
			  .attr('disabled', false)
			  .attr('title', 'Toggle deleted lines on/off');
		  tr.find('.diff-added-line-count')
			  .attr('disabled', false)
			  .attr('title', 'Toggle added lines on/off');

		  cd.radioEntrySwitch(previousFilenameNode, filenameNode);
		  if (previousFilenameNode !== undefined) {
			diffFileDiv(getFilename(previousFilenameNode)).hide();
		  }
		  diffFileDiv(getFilename(filenameNode)).show();
		  previousFilenameNode = filenameNode;

		  if (sectionCount > 0 && (reselected || !cd.inArray(filename, alreadyOpened))) {
			var section = $('#' + id + '_section_' + sectionIndex);
			var downFromTop = 150;
			var halfSecond = 500;
			diffSheet.animate({
			  scrollTop: section.offset().top - diffSheet.offset().top - downFromTop
			  }, halfSecond);
			sectionIndex += 1;
			sectionIndex %= sectionCount;
		  }
		  alreadyOpened.push(filename);
		};
	  };

	  $.each(diffs, function(_n, diff) {
		var filenameNode = $('#radio_' + diff.id);
		var filename = getFilename(filenameNode);
		filenameNode.click(loadFrom(filename, filenameNode, diff.id, diff.section_count));
	  });
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffFilenames = $('#diff_filenames', diffDiv);

    var makeDiffFilenames = function(diffs) {

      var table= $('
');
      $.each(diffs, function(_, diff) {
		var tr = $('
');
		var td = $('', { 'class': 'align-left' });

        var filenameDiv = $('
', {
          'class': 'filename',
		  'id': 'radio_' + diff.id,
          'text': diff.filename
        });

		var deletedLineCountTd = undefined;
		if (diff.deleted_line_count > 0) {
		  deletedLineCountTd = $('', {
			'class': 'align-right diff-deleted-line-count button',
			'data-filename': diff.filename
		  });
		  deletedLineCountTd.append(diff.deleted_line_count);
		} else {
		  deletedLineCountTd = $('');
		}

		var addedLineCountTd = undefined;
		if (diff.added_line_count > 0) {
		  addedLineCountTd = $('', {
			'class': 'align-right diff-added-line-count button',
			'data-filename': diff.filename
		  });
		  addedLineCountTd.append(diff.added_line_count);
		} else {
		  addedLineCountTd = $('');
		}

		td.append(filenameDiv);
		tr.append(td);
		tr.append(deletedLineCountTd);
		tr.append(addedLineCountTd)
        table.append(tr);
      });

      return table.html();
    };

	var resetFilenameAddedDeletedLineCountHandlers = function() {
	  var display = function(node, name, value) {
		if ($(node).attr('disabled') !== 'disabled') {
		  var filename = $(node).data('filename');
		  var selector = '[id="' + filename + '_diff_div"] ' + name;
		  $(selector, diffDiv).css('display', value);
		}
	  };

	  $('.diff-deleted-line-count', diffDiv).clickToggle(
		function() { display(this, 'deleted', 'none' ); },
		function() { display(this, 'deleted', 'block'); }
	  );

	  $('.diff-added-line-count', diffDiv).clickToggle(
		function() { display(this, 'added', 'none' ); },
		function() { display(this, 'added', 'block'); }
	  );
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var showCurrentFile = function(filenameId) {
	  $('#radio_' + filenameId).click();
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffDialog = diffDiv.dialog({
	  title: cd.dialogTitle(title),
	  autoOpen: false,
	  width: 1100,
	  modal: true,
	  buttons: {
		close: function() {
		  $(this).dialog('close');
		}
	  }
	});

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var refresh = function() {
	  $.getJSON('/differ/diff',
		{
		  id: id,
		  avatar: avatarName,
		  was_tag: wasTag,
		  now_tag: nowTag
		},
		function(data) {
		  resetNavigateButtonHandlers();

		  wasTrafficLight.html(makeTrafficLight(data.wasTrafficLight));
		  wasTagNumber.val(wasTag);
		  tagGapNumber.html(tagGap);
		  nowTagNumber.val(nowTag);
		  nowTrafficLight.html(makeTrafficLight(data.nowTrafficLight));

		  diffFilenames.html(makeDiffFilenames(data.diffs));
		  resetFilenameAddedDeletedLineCountHandlers();
		  diffContent.html(makeDiffContent(data.diffs));
          buildDiffFilenameHandlers(data.idsAndSectionCounts);
          showCurrentFile(data.currentFilenameId);
		}
	  );
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	diffDialog.dialog('open');
	refresh();

  }; // cd.dialog_diff = function(title, id, avatarName, wasTag, nowTag, maxTag) {

  return cd;
})(cyberDojo || {}, $);

<commit_msg>diff-dialog traffic-lights for old format (:outcome -> :colour)<commit_after>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.setupTrafficLightOpensDiffDialogHandlers = function(nodes, title) {
	nodes.click(function() {
	  var id = $(this).data('id');
	  var avatarName = $(this).data('avatar-name');
	  var wasTag = $(this).data('was-tag');
	  var nowTag = $(this).data('now-tag');
	  var maxTag = $(this).data('max-tag');
	  cd.dialog_diff(title, id, avatarName, wasTag, nowTag, maxTag);
	});
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.dialog_diff = function(title, id, avatarName, wasTag, nowTag, maxTag) {

  	var minTag = 0;
    var tagGap = nowTag - wasTag;

    var makeDiffInfo = function() {
	  return '' +
	    '
' +
		  '
' +
		    '' +
			  '
' +
			  '
' +
		    '	' +
			'' +
			  '<input type="text" id="was_tag_number" value="' + wasTag + '" />' +
			'	' +
			'' +
			  '←' +
			'	' +
			'' +
			  '
' +
			    tagGap +
			  '
' +
			'	' +
			'' +
			  '→' +
			'	' +
			'' +
			  '<input type="text" id="now_tag_number" value="' + nowTag + '" />' +
			'	' +
		    '' +
			  '
' +
			  '
' +
		    '	' +
		  '
' +
		'
';
    };

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

    var makeDiffDiv = function()  {
      var div = $('
', {
        'id': 'diff_dialog'
      });
      var table = $('
');
      table.append(
        "
" +
          "" +

		    "
" +
			  "
" +
				"" +
			      makeDiffInfo() +
			    "	" +
			  "
" +

			  "
" +
				"" +
				  cd.makeNavigateButtons(avatarName) +
				"	" +
			  "
" +

			  "
" +
				"" +
				  "
" +
				  "
" +
				"	" +
			  "
" +

			"
" +

          "	" +
          "" +
            "
" +
		    "
" +
          "	" +
	    "
");

      div.append(table);
      return div;
    };

    var diffDiv = makeDiffDiv();

    //- - - - - - - - - - - - - - - - - - - - - - - - - -
    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var wasTagNumber = $('#was_tag_number', diffDiv);
	var tagGapNumber = $('#tag_gap_number', diffDiv);
	var nowTagNumber = $('#now_tag_number', diffDiv);

	var wasTrafficLight = $('#was_traffic_light', diffDiv);
	var nowTrafficLight = $('#now_traffic_light', diffDiv);

	var firstButton = $('#first_button', diffDiv);
	var prevButton  = $('#prev_button',  diffDiv);
	var nextButton  = $('#next_button',  diffDiv);
	var lastButton  = $('#last_button',  diffDiv);

    var resetNavigateButtonHandlers = function() {

	  var toolTip = function(was, now) {
		if (was !== now) {
		  return 'Show diff of ' + was + ' <-> ' + now;
		} else {
		  return 'Show ' + was;
		}
	  };

	  var showDiff = function(was,now) {
		wasTag = was;
		nowTag = now;
		tagGap = now - was;
		refresh();
	  };

	  var tagEdit = function(event) {
		if (event.keyCode === $.ui.keyCode.ENTER) {
		  var newWasTag = parseInt(wasTagNumber.val(), 10);
		  var newNowTag = parseInt(nowTagNumber.val(), 10);
		  if (isNaN(newWasTag) || newWasTag < minTag ||
				isNaN(newNowTag) || newNowTag > maxTag ||
				  newWasTag > newNowTag) {
			wasTagNumber.val(wasTag);
			nowTagNumber.val(nowTag);
		  } else {
			showDiff(newWasTag, newNowTag);
		  }
		}
	  };

	  var refreshNavigationHandlers = function(off, button, from, to) {
		button.attr('disabled', off);
		if (!off) {
		  button.unbind()
			.click(function() { showDiff(from, to); })
			.attr('title', toolTip(from, to));
		}
	  };

	  // The wasTagNumber and nowTagNumber may have been edited since the
	  // refresh but before a navigation button is pressed. However, the
	  // navigation buttons do _not_ look at the current state of the
	  // wasTagNumber/nowTagNumbers, but use the values set on refresh.
	  // This is the simplest way to ensure the navigation buttons are
	  // not incorrectly enabled/disabled.
	  refreshNavigationHandlers(minTag >= wasTag, firstButton, minTag, minTag+tagGap);
	  refreshNavigationHandlers(minTag >= wasTag, prevButton, wasTag-1, nowTag-1);
	  refreshNavigationHandlers(nowTag >= maxTag, nextButton, wasTag+1, nowTag+1);
	  refreshNavigationHandlers(nowTag >= maxTag, lastButton, maxTag-tagGap, maxTag);

	  wasTagNumber.unbind().keyup(function(event) { tagEdit(event); });
	  nowTagNumber.unbind().keyup(function(event) { tagEdit(event); });
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

  	var makeTrafficLight = function(trafficLight) {
	  // old increments.rb files used light[:outcome]
	  var colour = trafficLight.colour || trafficLight.outcome
      var filename = 'traffic_light_' + colour;
      return '' +
		"";
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffContent = $('#diff_content', diffDiv);

    var makeDiffContent = function(diffs) {
	  var span = $('');
	  $.each(diffs, function(_, diff) {
		var divHolder = $('
', {
		  id: diff.filename + '_diff_div',
		  'class': 'filename_div'
		});
		var div = $('
', {
		  id: 'diff_file_content_for_' + diff.filename,
		  'class': 'diff_sheet'
		});
		div.html(diff.content);
		divHolder.append(div);
		span.append(divHolder);
	  });
	  return span;
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var buildDiffFilenameHandlers = function(diffs) {
	  // Builds the diff filename click handlers for a given kata-id,
	  // given animal-name, and given traffic-light was/now numbers.
	  // Clicking on the filename brings it into view by hiding the
	  // previously selected file and showing the selected one.
	  //
	  // The first time the filename for a file with one or more
	  // diff-sections is clicked its diff-section is scrolled into view.
	  //
	  // Subsequent times if you click on the filename you will _not_ get
	  // an autoscroll. This is so that the scrollPos of a diff that has
	  // been manually scrolled is retained.
	  //
	  // However, if filename X is open and you reclick on filename X
	  // then you _will_ get an autoscroll to the _next_ diff-section in that
	  // diff (which will cycle round).

	  var previousFilenameNode;
	  var alreadyOpened = [ ];
	  var getFilename = function(node) {
		return $.trim(node.text());
	  };

	  var diffFileContentFor = function(filename) {
		return cd.id('diff_file_content_for_' + filename);
	  };

	  var diffFileDiv = function(filename) {
		return cd.id(filename + '_diff_div');
	  };

	  var loadFrom = function(filename, filenameNode, id, sectionCount) {

		var diffSheet = diffFileContentFor(filename);
		var sectionIndex = 0;

		if (sectionCount > 0) {
			filenameNode.attr('title', 'Auto-scroll through diffs');
		}

		return function() {
		  var reselected =
			previousFilenameNode !== undefined && getFilename(previousFilenameNode) === filename;

		  var allLineCountButtons = $('.diff-deleted-line-count, .diff-added-line-count');
		  var off = { 'disabled':true, 'title':'' };
		  var disableAllLineCountButtons = function() {
			allLineCountButtons.attr(off);
		  };
		  var tr = filenameNode.closest('tr');
		  disableAllLineCountButtons();
		  tr.find('.diff-deleted-line-count')
			  .attr('disabled', false)
			  .attr('title', 'Toggle deleted lines on/off');
		  tr.find('.diff-added-line-count')
			  .attr('disabled', false)
			  .attr('title', 'Toggle added lines on/off');

		  cd.radioEntrySwitch(previousFilenameNode, filenameNode);
		  if (previousFilenameNode !== undefined) {
			diffFileDiv(getFilename(previousFilenameNode)).hide();
		  }
		  diffFileDiv(getFilename(filenameNode)).show();
		  previousFilenameNode = filenameNode;

		  if (sectionCount > 0 && (reselected || !cd.inArray(filename, alreadyOpened))) {
			var section = $('#' + id + '_section_' + sectionIndex);
			var downFromTop = 150;
			var halfSecond = 500;
			diffSheet.animate({
			  scrollTop: section.offset().top - diffSheet.offset().top - downFromTop
			  }, halfSecond);
			sectionIndex += 1;
			sectionIndex %= sectionCount;
		  }
		  alreadyOpened.push(filename);
		};
	  };

	  $.each(diffs, function(_n, diff) {
		var filenameNode = $('#radio_' + diff.id);
		var filename = getFilename(filenameNode);
		filenameNode.click(loadFrom(filename, filenameNode, diff.id, diff.section_count));
	  });
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffFilenames = $('#diff_filenames', diffDiv);

    var makeDiffFilenames = function(diffs) {

      var table= $('
');
      $.each(diffs, function(_, diff) {
		var tr = $('
');
		var td = $('', { 'class': 'align-left' });

        var filenameDiv = $('
', {
          'class': 'filename',
		  'id': 'radio_' + diff.id,
          'text': diff.filename
        });

		var deletedLineCountTd = undefined;
		if (diff.deleted_line_count > 0) {
		  deletedLineCountTd = $('', {
			'class': 'align-right diff-deleted-line-count button',
			'data-filename': diff.filename
		  });
		  deletedLineCountTd.append(diff.deleted_line_count);
		} else {
		  deletedLineCountTd = $('');
		}

		var addedLineCountTd = undefined;
		if (diff.added_line_count > 0) {
		  addedLineCountTd = $('', {
			'class': 'align-right diff-added-line-count button',
			'data-filename': diff.filename
		  });
		  addedLineCountTd.append(diff.added_line_count);
		} else {
		  addedLineCountTd = $('');
		}

		td.append(filenameDiv);
		tr.append(td);
		tr.append(deletedLineCountTd);
		tr.append(addedLineCountTd)
        table.append(tr);
      });

      return table.html();
    };

	var resetFilenameAddedDeletedLineCountHandlers = function() {
	  var display = function(node, name, value) {
		if ($(node).attr('disabled') !== 'disabled') {
		  var filename = $(node).data('filename');
		  var selector = '[id="' + filename + '_diff_div"] ' + name;
		  $(selector, diffDiv).css('display', value);
		}
	  };

	  $('.diff-deleted-line-count', diffDiv).clickToggle(
		function() { display(this, 'deleted', 'none' ); },
		function() { display(this, 'deleted', 'block'); }
	  );

	  $('.diff-added-line-count', diffDiv).clickToggle(
		function() { display(this, 'added', 'none' ); },
		function() { display(this, 'added', 'block'); }
	  );
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var showCurrentFile = function(filenameId) {
	  $('#radio_' + filenameId).click();
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var diffDialog = diffDiv.dialog({
	  title: cd.dialogTitle(title),
	  autoOpen: false,
	  width: 1100,
	  modal: true,
	  buttons: {
		close: function() {
		  $(this).dialog('close');
		}
	  }
	});

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	var refresh = function() {
	  $.getJSON('/differ/diff',
		{
		  id: id,
		  avatar: avatarName,
		  was_tag: wasTag,
		  now_tag: nowTag
		},
		function(data) {
		  resetNavigateButtonHandlers();

		  wasTrafficLight.html(makeTrafficLight(data.wasTrafficLight));
		  wasTagNumber.val(wasTag);
		  tagGapNumber.html(tagGap);
		  nowTagNumber.val(nowTag);
		  nowTrafficLight.html(makeTrafficLight(data.nowTrafficLight));

		  diffFilenames.html(makeDiffFilenames(data.diffs));
		  resetFilenameAddedDeletedLineCountHandlers();
		  diffContent.html(makeDiffContent(data.diffs));
          buildDiffFilenameHandlers(data.idsAndSectionCounts);
          showCurrentFile(data.currentFilenameId);
		}
	  );
	};

    //- - - - - - - - - - - - - - - - - - - - - - - - - -

	diffDialog.dialog('open');
	refresh();

  }; // cd.dialog_diff = function(title, id, avatarName, wasTag, nowTag, maxTag) {

  return cd;
})(cyberDojo || {}, $);

<|endoftext|>


<commit_before>// adjust toolbar style, set the toolbar left position and inner ul width
var dynamicToolbar = function(initial){
  var $headers = $(".grid-header");
  $headers.each(function(){
    var $header = $(this);
    var $toolbar_wrapper = $(this).find(".toolbar-wrapper");
    var $toolbar = $toolbar_wrapper.find(".toolbar");

    // get the current right visible item index before other operation
    var rightVisibleIndex = findEageItemsOnRight($toolbar_wrapper, $toolbar).visibleItemIndex;

    // set toolbar original left position
    var left = 0;
    $toolbar_wrapper.prevAll().each(function(){
      left += $(this).outerWidth() + parseFloat($(this).css("margin-left")) + parseFloat($(this).css("margin-right"));
    })
    left += 50;
    $toolbar_wrapper.css("left", left);

    if(initial) {
      // set inner toolbar fixed width
      var listWidth = 0;
      $toolbar.find("li").each(function(){
        listWidth += parseFloat($(this).outerWidth());
      });
      $toolbar.css('width', listWidth);
    }

    //if($toolbar_wrapper.width())
    adjustToolbarLeftPosition($toolbar_wrapper, $toolbar, rightVisibleIndex, initial);
  });
}

// Adjust the toolbar left position if the screen if not big enough
var adjustToolbarLeftPosition = function($toolbar_wrapper, $toolbar, rightVisibleIndex, initial){
  // adjust the toolbar left position if the most left item not fully displayed
  var oldLeft = parseFloat($toolbar_wrapper.css("left"));

  var smallEnough = false;
  var newLeft = oldLeft;
  var remainingWidth = $toolbar_wrapper.outerWidth();
  var remainingWidthClone = remainingWidth;

  // check small enough
  $($toolbar.find("li").get().reverse()).each(function(){
    remainingWidth -= $(this).outerWidth();
    var previousItemWidth = $(this).prev().outerWidth();
    if(remainingWidth < previousItemWidth) {
      smallEnough = true;
      return false;
    }
  });

  $($toolbar.find("li").get().slice(0, rightVisibleIndex).reverse()).each(function(){
    remainingWidthClone -= $(this).outerWidth();
    var previousItemWidth = $(this).prev().outerWidth();
    if(remainingWidthClone < previousItemWidth) {
      newLeft = oldLeft + remainingWidthClone;
      $toolbar_wrapper.css("left", newLeft);
      return false;
    }
  });
  // hide prev and next button when window is wider enough, otherwise show them
  if(!smallEnough) {
    $toolbar_wrapper.siblings("span.tb_prev, span.tb_next").addClass("hidden");
    // also, show all items
    $toolbar_wrapper.find(".toolbar").css("left", 0);
  } else {
    // make sure the first toolbar item always align left or more of toolbar_wrapper (otherwise there is a blank between first item and prev button)
    if($toolbar.offset().left > $toolbar_wrapper.offset().left) {
      $toolbar.css("left", 0);
    }
    var prevLeft = newLeft - $toolbar_wrapper.siblings("span.tb_prev").outerWidth();
    $toolbar_wrapper.siblings("span.tb_prev").css("left", prevLeft);
    $toolbar_wrapper.siblings("span.tb_prev, span.tb_next").removeClass("hidden");
  }
}

// find the 2 items on the toolbar left eage (visible one and invisible one)
var findEageItemsOnLeft = function($toolbar_wrapper, $toolbar){
  var visibleItemWidth;
  var invisibleItemWidth;
  var visibleItemIndex = $toolbar.find(".toolbar_item").length;
  var mostLeft = true;
  var toolbarWrapperLeft = $toolbar_wrapper.offset().left;
  $($toolbar.find(".toolbar_item").get().reverse()).each(function(){
    var currentItemLeft = $(this).offset().left;
    if(currentItemLeft < toolbarWrapperLeft) {
      invisibleItemWidth = $(this).outerWidth();
      visibleItemWidth = $(this).next().outerWidth();
      mostLeft = false;
      return false;
    }
    visibleItemIndex--;
  });
  // if mostLeft
  if(mostLeft) {
    invisibleItemWidth = 0;
    visibleItemWidth = $toolbar.find(".toolbar_item").first().outerWidth();
  }
  return {mostLeft: mostLeft, visibleItemIndex: visibleItemIndex, visibleItemWidth: visibleItemWidth, invisibleItemWidth: invisibleItemWidth};
}

// find the 2 items on the toolbar right eage (visible one and invisible one)
var findEageItemsOnRight = function($toolbar_wrapper, $toolbar){
  var visibleItemWidth;
  var invisibleItemWidth;
  var visibleItemIndex = 0;
  var mostRight = true;
  var toolbarWrapperRight = $toolbar_wrapper.offset().left + $toolbar_wrapper.width();
  $toolbar.find(".toolbar_item").each(function(){
    var currentItemRight = $(this).offset().left + $(this).outerWidth();
    if(currentItemRight > toolbarWrapperRight) {
      invisibleItemWidth = $(this).outerWidth();
      visibleItemWidth = $(this).prev().outerWidth();
      mostRight = false;
      return false;
    }
    visibleItemIndex++;
  });
  // if mostRight
  if(mostRight) {
    invisibleItemWidth = 0;
    visibleItemWidth = $toolbar.find(".toolbar_item").last().outerWidth();
  }
  return {mostRight: mostRight, visibleItemIndex: visibleItemIndex, visibleItemWidth: visibleItemWidth, invisibleItemWidth: invisibleItemWidth};
}

// After clicking prev or next, if the widths of item appeared and disappeared are different, should adjust the left position of toolbar wrapper
var adjustWrapperPositionAfterShift = function($toolbar_wrapper, offset){
  var $prev = $toolbar_wrapper.siblings(".tb_prev");
  var newWrapperLeft = parseFloat($toolbar_wrapper.css("left")) + offset;
  var newPrevLeft = parseFloat($prev.css("left")) + offset;
  $toolbar_wrapper.css("left", newWrapperLeft);
  $prev.css("left", newPrevLeft);
}

// Click the prev button
$(".grid-header .tb_prev").live('click', function(){
  var $prev = $(this);
  var $toolbar_wrapper = $(this).siblings(".toolbar-wrapper");
  var $toolbar = $toolbar_wrapper.find(".toolbar");

  var leftResult = findEageItemsOnLeft($toolbar_wrapper, $toolbar);
  var rightResult = findEageItemsOnRight($toolbar_wrapper, $toolbar);

  var mostLeft = leftResult.mostLeft;
  var shiftWidth = rightResult.visibleItemWidth;
  var leftPositionOffset = shiftWidth - leftResult.invisibleItemWidth

  // If not reach the left eage, continue shift
  if(!mostLeft){
    $toolbar.animate({
      left: '+=' + shiftWidth
    }, 'slow', function(){
      // $prev.siblings(".tb_next").removeClass("hidden");
      // if(leftResult.visibleItemIndex == 1) {
      //   $prev.addClass("hidden");
      // }
      adjustWrapperPositionAfterShift($toolbar_wrapper, leftPositionOffset);
    });
  }
});

// CLick the next button
$(".grid-header .tb_next").live('click', function(){
  var $next = $(this);
  var $toolbar_wrapper = $(this).siblings(".toolbar-wrapper");
  var $toolbar = $toolbar_wrapper.find(".toolbar");

  var leftResult = findEageItemsOnLeft($toolbar_wrapper, $toolbar);
  var rightResult = findEageItemsOnRight($toolbar_wrapper, $toolbar);

  var mostRight = rightResult.mostRight;
  var shiftWidth = rightResult.invisibleItemWidth;
  var leftPositionOffset = leftResult.visibleItemWidth - shiftWidth;

  // If not reach the right eager, continue shift
  if(!mostRight) {
    $toolbar.animate({
      left: '-=' + shiftWidth
    }, 'slow', function(){
      // $next.siblings(".tb_prev").removeClass("hidden");
      // if(rightResult.visibleItemIndex == $toolbar.find(".toolbar_item").length - 1) {
      //   $next.addClass("hidden");
      // }
      adjustWrapperPositionAfterShift($toolbar_wrapper, leftPositionOffset);
    });
  }
});

// Resize window
$(window).resize(function(){
  dynamicToolbar(false);
});
<commit_msg>BUG #11128 1h - Grid toolbar, when the first item is wider, the dynamic length change has bug<commit_after>// adjust toolbar style, set the toolbar left position and inner ul width
var dynamicToolbar = function(initial){
  var $headers = $(".grid-header");
  $headers.each(function(){
    var $header = $(this);
    var $toolbar_wrapper = $(this).find(".toolbar-wrapper");
    var $toolbar = $toolbar_wrapper.find(".toolbar");

    // get the current right visible item index before other operation
    var rightVisibleIndex = findEageItemsOnRight($toolbar_wrapper, $toolbar).visibleItemIndex;

    // set toolbar original left position
    var left = 0;
    $toolbar_wrapper.prevAll().each(function(){
      left += $(this).outerWidth() + parseFloat($(this).css("margin-left")) + parseFloat($(this).css("margin-right"));
    })
    left += 50;
    $toolbar_wrapper.css("left", left);

    if(initial) {
      // set inner toolbar fixed width
      var listWidth = 0;
      $toolbar.find("li").each(function(){
        listWidth += parseFloat($(this).outerWidth());
      });
      $toolbar.css('width', listWidth);
    }

    //if($toolbar_wrapper.width())
    adjustToolbarLeftPosition($toolbar_wrapper, $toolbar, rightVisibleIndex, initial);
  });
}

// Adjust the toolbar left position if the screen if not big enough
var adjustToolbarLeftPosition = function($toolbar_wrapper, $toolbar, rightVisibleIndex, initial){
  // adjust the toolbar left position if the most left item not fully displayed
  var oldLeft = parseFloat($toolbar_wrapper.css("left"));

  var smallEnough = false;
  var newLeft = oldLeft;
  var remainingWidth = $toolbar_wrapper.outerWidth();
  var remainingWidthClone = remainingWidth;

  // check small enough
  $($toolbar.find("li").get().reverse()).each(function(){
    remainingWidth -= $(this).outerWidth();
    var previousItemWidth = $(this).prev().outerWidth();
    if(remainingWidth < previousItemWidth) {
      smallEnough = true;
      return false;
    }
  });

  $($toolbar.find("li").get().slice(0, rightVisibleIndex).reverse()).each(function(){
    remainingWidthClone -= $(this).outerWidth();
    var previousItemWidth = $(this).prev().outerWidth();
    if(remainingWidthClone < previousItemWidth) {
      newLeft = oldLeft + remainingWidthClone;
      $toolbar_wrapper.css("left", newLeft);
      return false;
    }
  });
  // hide prev and next button when window is wider enough, otherwise show them
  if(!smallEnough) {
    $toolbar_wrapper.siblings("span.tb_prev, span.tb_next").addClass("hidden");
    // also, show all items
    $toolbar_wrapper.find(".toolbar").css("left", 0);
  } else {
    // make sure the first toolbar item always align left or more of toolbar_wrapper (otherwise there is a blank between first item and prev button)
    if($toolbar.offset().left > $toolbar_wrapper.offset().left) {
      $toolbar.css("left", 0);
    }
    var prevLeft = newLeft - $toolbar_wrapper.siblings("span.tb_prev").outerWidth();
    $toolbar_wrapper.siblings("span.tb_prev").css("left", prevLeft);
    $toolbar_wrapper.siblings("span.tb_prev, span.tb_next").removeClass("hidden");
  }
}

// find the 2 items on the toolbar left eage (visible one and invisible one)
var findEageItemsOnLeft = function($toolbar_wrapper, $toolbar){
  var visibleItemWidth;
  var invisibleItemWidth;
  var visibleItemIndex = $toolbar.find(".toolbar_item").length;
  var mostLeft = true;
  var toolbarWrapperLeft = $toolbar_wrapper.offset().left;
  $($toolbar.find(".toolbar_item").get().reverse()).each(function(){
    var currentItemLeft = Math.round($(this).offset().left);
    if(currentItemLeft < toolbarWrapperLeft) {
      invisibleItemWidth = $(this).outerWidth();
      visibleItemWidth = $(this).next().outerWidth();
      mostLeft = false;
      return false;
    }
    visibleItemIndex--;
  });
  // if mostLeft
  if(mostLeft) {
    invisibleItemWidth = 0;
    visibleItemWidth = $toolbar.find(".toolbar_item").first().outerWidth();
  }
  return {mostLeft: mostLeft, visibleItemIndex: visibleItemIndex, visibleItemWidth: visibleItemWidth, invisibleItemWidth: invisibleItemWidth};
}

// find the 2 items on the toolbar right eage (visible one and invisible one)
var findEageItemsOnRight = function($toolbar_wrapper, $toolbar){
  var visibleItemWidth;
  var invisibleItemWidth;
  var visibleItemIndex = 0;
  var mostRight = true;
  var toolbarWrapperRight = $toolbar_wrapper.offset().left + $toolbar_wrapper.width();
  $toolbar.find(".toolbar_item").each(function(){
    var currentItemRight = Math.round($(this).offset().left + $(this).outerWidth());
    if(currentItemRight > toolbarWrapperRight) {
      invisibleItemWidth = $(this).outerWidth();
      visibleItemWidth = $(this).prev().outerWidth();
      mostRight = false;
      return false;
    }
    visibleItemIndex++;
  });
  // if mostRight
  if(mostRight) {
    invisibleItemWidth = 0;
    visibleItemWidth = $toolbar.find(".toolbar_item").last().outerWidth();
  }
  return {mostRight: mostRight, visibleItemIndex: visibleItemIndex, visibleItemWidth: visibleItemWidth, invisibleItemWidth: invisibleItemWidth};
}

// After clicking prev or next, if the widths of item appeared and disappeared are different, should adjust the left position of toolbar wrapper
var adjustWrapperPositionAfterShift = function($toolbar_wrapper, offset){
  var $prev = $toolbar_wrapper.siblings(".tb_prev");
  var newWrapperLeft = parseFloat($toolbar_wrapper.css("left")) + offset;
  var newPrevLeft = parseFloat($prev.css("left")) + offset;
  $toolbar_wrapper.css("left", newWrapperLeft);
  $prev.css("left", newPrevLeft);
}

// Click the prev button
$(".grid-header .tb_prev").live('click', function(){
  var $prev = $(this);
  var $toolbar_wrapper = $(this).siblings(".toolbar-wrapper");
  var $toolbar = $toolbar_wrapper.find(".toolbar");

  var leftResult = findEageItemsOnLeft($toolbar_wrapper, $toolbar);
  var rightResult = findEageItemsOnRight($toolbar_wrapper, $toolbar);

  var mostLeft = leftResult.mostLeft;
  var shiftWidth = rightResult.visibleItemWidth;
  var leftPositionOffset = shiftWidth - leftResult.invisibleItemWidth

  // If not reach the left eage, continue shift
  if(!mostLeft){
    $toolbar.animate({
      left: '+=' + shiftWidth
    }, 'slow', function(){
      // $prev.siblings(".tb_next").removeClass("hidden");
      // if(leftResult.visibleItemIndex == 1) {
      //   $prev.addClass("hidden");
      // }
      adjustWrapperPositionAfterShift($toolbar_wrapper, leftPositionOffset);
    });
  }
});

// CLick the next button
$(".grid-header .tb_next").live('click', function(){
  var $next = $(this);
  var $toolbar_wrapper = $(this).siblings(".toolbar-wrapper");
  var $toolbar = $toolbar_wrapper.find(".toolbar");

  var leftResult = findEageItemsOnLeft($toolbar_wrapper, $toolbar);
  var rightResult = findEageItemsOnRight($toolbar_wrapper, $toolbar);

  var mostRight = rightResult.mostRight;
  var shiftWidth = rightResult.invisibleItemWidth;
  var leftPositionOffset = leftResult.visibleItemWidth - shiftWidth;

  // If not reach the right eager, continue shift
  if(!mostRight) {
    $toolbar.animate({
      left: '-=' + shiftWidth
    }, 'slow', function(){
      // $next.siblings(".tb_prev").removeClass("hidden");
      // if(rightResult.visibleItemIndex == $toolbar.find(".toolbar_item").length - 1) {
      //   $next.addClass("hidden");
      // }
      adjustWrapperPositionAfterShift($toolbar_wrapper, leftPositionOffset);
    });
  }
});

// Resize window
$(window).resize(function(){
  dynamicToolbar(false);
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var omit = require( './../lib' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof omit, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function throws an error if provided a source object argument which is not an object', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( value, 'a' );
		};
	}
});

tape( 'the function throws an error if provided a source object argument which is not an object', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( value,  [ 'a' ] );
		};
	}
});

tape( 'the function throws an error if provided a second argument which is neither a string or an array of strings', function test( t ) {
	var values;
	var i;

	values = [
		5,
		NaN,
		null,
		undefined,
		true,
		{},
		[],
		function noop() {}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( {}, value );
		};
	}
});

tape( 'the function returns a partial copy of an object omitting specified keys (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, [ 'b', 'c', 'e' ] );

	expected = {
		'a': 1,
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns a partial copy of an object omitting a specified key (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, 'b' );

	expected = {
		'a': 1,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns ignores non-existent key paths (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, [ 'b', 'c', 'e', 'f', 'g', 'beep', 'a' ] );

	expected = {
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns ignores non-existent key paths (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, 'beep' );

	expected = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores inherited properties (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	function Foo() {
		this.a = 1;
		this.b = 2;
		this.c = 3;
		this.d = 4;
		this.e = 5;
		return this;
	}

	Foo.prototype.f = 6;
	Foo.prototype.g = 7;

	obj1 = new Foo();

	obj2 = omit( obj1, [ 'b', 'c', 'e', 'f', 'g' ] );

	expected = {
		'a': 1,
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores inherited properties (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	function Foo() {
		this.a = 1;
		this.b = 2;
		this.c = 3;
		this.d = 4;
		this.e = 5;
		return this;
	}

	Foo.prototype.f = 6;
	Foo.prototype.g = 7;

	obj1 = new Foo();

	obj2 = omit( obj1, 'f' );

	expected = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns accepts non-plain objects', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = [ 0, 1, 2, 3, 4, 5 ];

	obj2 = omit( obj1, [ '0', '2', '4' ] );

	expected = {
		'1': 1,
		'3': 3,
		'5': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns a shallow copy (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': [ 1 ],
		'b': [ 2 ],
		'c': [ 3 ],
		'd': [ 4 ],
		'e': [ 5 ]
	};

	obj2 = omit( obj1, 'b' );

	expected = {
		'a': obj1.a,
		'c': obj1.c,
		'd': obj1.d,
		'e': obj1.e
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.strictEqual( obj2.a, obj1.a, 'returns shallow copy' );
	t.strictEqual( obj2.c, obj1.c, 'returns shallow copy' );
	t.strictEqual( obj2.d, obj1.d, 'returns shallow copy' );
	t.strictEqual( obj2.e, obj1.e, 'returns shallow copy' );

	t.end();
});

tape( 'the function returns a shallow copy (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': [ 1 ],
		'b': [ 2 ],
		'c': [ 3 ],
		'd': [ 4 ],
		'e': [ 5 ]
	};

	obj2 = omit( obj1, [ 'b', 'c' ] );

	expected = {
		'a': obj1.a,
		'd': obj1.d,
		'e': obj1.e
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.strictEqual( obj2.a, obj1.a, 'returns shallow copy' );
	t.strictEqual( obj2.d, obj1.d, 'returns shallow copy' );
	t.strictEqual( obj2.e, obj1.e, 'returns shallow copy' );

	t.end();
});
<commit_msg>Fix test descriptions and lint error<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var omit = require( './../lib' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof omit, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function throws an error if provided a source object argument which is not an object', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( value, 'a' );
		};
	}
});

tape( 'the function throws an error if provided a source object argument which is not an object', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( value, [ 'a' ] );
		};
	}
});

tape( 'the function throws an error if provided a second argument which is neither a string nor an array of strings', function test( t ) {
	var values;
	var i;

	values = [
		5,
		NaN,
		null,
		undefined,
		true,
		{},
		[],
		function noop() {}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			omit( {}, value );
		};
	}
});

tape( 'the function returns a partial copy of an object omitting specified keys (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, [ 'b', 'c', 'e' ] );

	expected = {
		'a': 1,
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns a partial copy of an object omitting a specified key (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, 'b' );

	expected = {
		'a': 1,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores non-existent key paths (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, [ 'b', 'c', 'e', 'f', 'g', 'beep', 'a' ] );

	expected = {
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores non-existent key paths (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	obj2 = omit( obj1, 'beep' );

	expected = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores inherited properties (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	function Foo() {
		this.a = 1;
		this.b = 2;
		this.c = 3;
		this.d = 4;
		this.e = 5;
		return this;
	}

	Foo.prototype.f = 6;
	Foo.prototype.g = 7;

	obj1 = new Foo();

	obj2 = omit( obj1, [ 'b', 'c', 'e', 'f', 'g' ] );

	expected = {
		'a': 1,
		'd': 4
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function ignores inherited properties (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	function Foo() {
		this.a = 1;
		this.b = 2;
		this.c = 3;
		this.d = 4;
		this.e = 5;
		return this;
	}

	Foo.prototype.f = 6;
	Foo.prototype.g = 7;

	obj1 = new Foo();

	obj2 = omit( obj1, 'f' );

	expected = {
		'a': 1,
		'b': 2,
		'c': 3,
		'd': 4,
		'e': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function accepts non-plain objects', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = [ 0, 1, 2, 3, 4, 5 ];

	obj2 = omit( obj1, [ '0', '2', '4' ] );

	expected = {
		'1': 1,
		'3': 3,
		'5': 5
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.end();
});

tape( 'the function returns a shallow copy (string)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': [ 1 ],
		'b': [ 2 ],
		'c': [ 3 ],
		'd': [ 4 ],
		'e': [ 5 ]
	};

	obj2 = omit( obj1, 'b' );

	expected = {
		'a': obj1.a,
		'c': obj1.c,
		'd': obj1.d,
		'e': obj1.e
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.strictEqual( obj2.a, obj1.a, 'returns shallow copy' );
	t.strictEqual( obj2.c, obj1.c, 'returns shallow copy' );
	t.strictEqual( obj2.d, obj1.d, 'returns shallow copy' );
	t.strictEqual( obj2.e, obj1.e, 'returns shallow copy' );

	t.end();
});

tape( 'the function returns a shallow copy (strings)', function test( t ) {
	var expected;
	var obj1;
	var obj2;

	obj1 = {
		'a': [ 1 ],
		'b': [ 2 ],
		'c': [ 3 ],
		'd': [ 4 ],
		'e': [ 5 ]
	};

	obj2 = omit( obj1, [ 'b', 'c' ] );

	expected = {
		'a': obj1.a,
		'd': obj1.d,
		'e': obj1.e
	};

	t.deepEqual( obj2, expected, 'returns expected object' );
	t.strictEqual( obj2.a, obj1.a, 'returns shallow copy' );
	t.strictEqual( obj2.d, obj1.d, 'returns shallow copy' );
	t.strictEqual( obj2.e, obj1.e, 'returns shallow copy' );

	t.end();
});
<|endoftext|>


<commit_before>/* global HDO */

(function (HDO) {
  HDO.votePropositionFetcher = {
    create: function () {
      var instance = Object.create(this);
      return instance;
    },

    init: function () {
      $(document.body).delegate('[data-vote-id]', 'click', function () {
        var voteId, target;

        voteId = $(this).data('vote-id');
        target = $('#proposition-body-' + voteId);

        target.toggle();

        if (target.data('fetched')) {
          return;
        }

        var spinner = target.find(".spinner");
        spinner.show();

        $.ajax({
          url: "/votes/" + voteId + "/propositions",
          type: "GET",
          dataType: "html",

          complete: function () {
            spinner.hide();
          },

          success: function (data) {
            target.data('fetched', true);
            target.html(data);
          },

          error: function () {
            target.html('Feil under henting av forslagstekst.');
          }
        });
      });
    }
  };
}(HDO));
<commit_msg>JS style fix.<commit_after>/* global HDO */

(function (HDO) {
  HDO.votePropositionFetcher = {
    create: function () {
      var instance = Object.create(this);
      return instance;
    },

    init: function () {
      $(document.body).delegate('[data-vote-id]', 'click', function () {
        var voteId, target, spinner;

        voteId = $(this).data('vote-id');
        target = $('#proposition-body-' + voteId);

        target.toggle();

        if (target.data('fetched')) {
          return;
        }

        spinner = target.find(".spinner");
        spinner.show();

        $.ajax({
          url: "/votes/" + voteId + "/propositions",
          type: "GET",
          dataType: "html",

          complete: function () {
            spinner.hide();
          },

          success: function (data) {
            target.data('fetched', true);
            target.html(data);
          },

          error: function () {
            target.html('Feil under henting av forslagstekst.');
          }
        });
      });
    }
  };
}(HDO));
<|endoftext|>


<commit_before>import commandLineArgs from 'command-line-args';
import fs from 'fs';
import path from 'path';
import { globby } from 'globby';
import lunr from 'lunr';
import { getAllComponents } from './shared.js';

const { outdir } = commandLineArgs({ name: 'outdir', type: String });
const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.json'), 'utf8'));

console.log('Generating search index for documentation');

(async () => {
  function getHeadings(markdown, maxLevel = 6) {
    const headings = [];
    const lines = markdown.split('\n');

    lines.map(line => {
      if (line.startsWith('#')) {
        const level = line.match(/^(#+)/)[0].length;
        const content = line.replace(/^#+/, '');

        if (level <= maxLevel) {
          headings.push({ level, content });
        }
      }
    });

    return headings;
  }

  function getMembers(markdown) {
    const members = [];
    const headers = markdown.match(/\[component-header:([a-z-]+)\]/g);

    if (!headers) {
      return '';
    }

    headers.map(header => {
      const tagName = header.match(/\[component-header:([a-z-]+)\]/)[1];
      const component = getAllComponents(metadata).find(component => component.tagName === tagName);

      if (component) {
        const fields = ['members', 'cssProperties', 'cssParts', 'slots', 'events'];

        fields.map(field => {
          if (component[field]) {
            component[field].map(entry => {
              if (entry.name) members.push(entry.name);
              if (entry.description) members.push(entry.description);
              if (entry.attribute) members.push(entry.attribute);
            });
          }
        });
      }
    });

    return members.join(' ');
  }

  const files = await globby('./docs/**/*.md');
  const map = {};
  const searchIndex = lunr(function () {
    // The search index uses these field names extensively, so shortening them can save some serious bytes. The initial
    // index file went from 468 KB => 401 KB by using single-character names!
    this.ref('id'); // id
    this.field('t', { boost: 10 }); // title
    this.field('h', { boost: 5 }); // headings
    this.field('m', { boost: 2 }); // members (props, methods, events, etc.)
    this.field('c'); // content

    files.map((file, index) => {
      const relativePath = path.relative('./docs', file).replace(/\\/g, '/');
      const relativePathNoExtension = relativePath.split('.').slice(0, -1).join('.');
      const url = relativePath.replace(/\.md$/, '');
      const filename = path.basename(file);
      // Ignore certain directories and files
      if (relativePath.startsWith('assets/') || relativePath.startsWith('dist/') || filename === '_sidebar.md') {
        return false;
      }

      const content = fs.readFileSync(file, 'utf8');
      const allHeadings = getHeadings(content, 4);
      const title = allHeadings.find(heading => heading.level === 1)?.content || '';
      const headings = allHeadings
        .filter(heading => heading.level > 1)
        .map(heading => heading.content)
        .concat([relativePathNoExtension])
        .join(' ');
      const members = getMembers(content);

      // Remove markdown code fields from search results. This seems to make search results a bit more accurate and
      // reduces search.json from ~679 KB to ~455 KB.
      const prunedContent = content.replace(/```(.*?)```/gs, '');

      this.add({ id: index, t: title, h: headings, m: members, c: prunedContent });

      map[index] = { title, url };
    });
  });

  fs.writeFileSync('./docs/search.json', JSON.stringify({ searchIndex, map }), 'utf8');
})();
<commit_msg>remove 404 from search<commit_after>import commandLineArgs from 'command-line-args';
import fs from 'fs';
import path from 'path';
import { globby } from 'globby';
import lunr from 'lunr';
import { getAllComponents } from './shared.js';

const { outdir } = commandLineArgs({ name: 'outdir', type: String });
const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.json'), 'utf8'));

console.log('Generating search index for documentation');

(async () => {
  function getHeadings(markdown, maxLevel = 6) {
    const headings = [];
    const lines = markdown.split('\n');

    lines.map(line => {
      if (line.startsWith('#')) {
        const level = line.match(/^(#+)/)[0].length;
        const content = line.replace(/^#+/, '');

        if (level <= maxLevel) {
          headings.push({ level, content });
        }
      }
    });

    return headings;
  }

  function getMembers(markdown) {
    const members = [];
    const headers = markdown.match(/\[component-header:([a-z-]+)\]/g);

    if (!headers) {
      return '';
    }

    headers.map(header => {
      const tagName = header.match(/\[component-header:([a-z-]+)\]/)[1];
      const component = getAllComponents(metadata).find(component => component.tagName === tagName);

      if (component) {
        const fields = ['members', 'cssProperties', 'cssParts', 'slots', 'events'];

        fields.map(field => {
          if (component[field]) {
            component[field].map(entry => {
              if (entry.name) members.push(entry.name);
              if (entry.description) members.push(entry.description);
              if (entry.attribute) members.push(entry.attribute);
            });
          }
        });
      }
    });

    return members.join(' ');
  }

  const files = await globby('./docs/**/*.md');
  const map = {};
  const searchIndex = lunr(function () {
    // The search index uses these field names extensively, so shortening them can save some serious bytes. The initial
    // index file went from 468 KB => 401 KB by using single-character names!
    this.ref('id'); // id
    this.field('t', { boost: 10 }); // title
    this.field('h', { boost: 5 }); // headings
    this.field('m', { boost: 2 }); // members (props, methods, events, etc.)
    this.field('c'); // content

    files.forEach((file, index) => {
      const relativePath = path.relative('./docs', file).replace(/\\/g, '/');
      const relativePathNoExtension = relativePath.split('.').slice(0, -1).join('.');
      const url = relativePath.replace(/\.md$/, '');
      const filename = path.basename(file);
      // Ignore certain directories and files
      if (
        relativePath.startsWith('assets/') ||
        relativePath.startsWith('dist/') ||
        filename === '_sidebar.md' ||
        filename === '404.md'
      ) {
        return false;
      }

      const content = fs.readFileSync(file, 'utf8');
      const allHeadings = getHeadings(content, 4);
      const title = allHeadings.find(heading => heading.level === 1)?.content || '';
      const headings = allHeadings
        .filter(heading => heading.level > 1)
        .map(heading => heading.content)
        .concat([relativePathNoExtension])
        .join(' ');
      const members = getMembers(content);

      // Remove markdown code fields from search results. This seems to make search results a bit more accurate and
      // reduces search.json from ~679 KB to ~455 KB.
      const prunedContent = content.replace(/```(.*?)```/gs, '');

      this.add({ id: index, t: title, h: headings, m: members, c: prunedContent });

      map[index] = { title, url };
    });
  });

  fs.writeFileSync('./docs/search.json', JSON.stringify({ searchIndex, map }), 'utf8');
})();
<|endoftext|>


<commit_before>import { css } from 'styled-components';

const SIZES = {
  mobile: 640,
};

const media = Object.keys(SIZES)
  .reduce((acc, label) => {
    acc[label] = (...args) => css`
      @media (max-width: ${SIZES[label] / 16}em) {
        ${css(...args)}
      }
    `;

    return acc;
  }, {});

export default {
  emptySpaceWidth: '0.33em',
  headerHeight: '50px',
  blockWidth: '315px', // TODO: 19.5em
  blockGutter: '10px', // TODO: 1em
  containerOffset: '100px', // TODO: Something based on real values
  media,
};
<commit_msg>Imports the existing z-indexes<commit_after>import { css } from 'styled-components';

const SIZES = {
  mobile: 640,
};

const media = Object.keys(SIZES)
  .reduce((acc, label) => {
    acc[label] = (...args) => css`
      @media (max-width: ${SIZES[label] / 16}em) {
        ${css(...args)}
      }
    `;

    return acc;
  }, {});

const Z_INDEXES = {
  header: 4001,
  dropdown: 4002,
  loader: 5001,
  modal: 6001,
  lightbox: 6001,
  rotate: 7001,
};

export default {
  emptySpaceWidth: '0.33em',
  headerHeight: '50px',
  blockWidth: '315px', // TODO: 19.5em
  blockGutter: '10px', // TODO: 1em
  containerOffset: '100px', // TODO: Something based on real values
  media,
  z: Z_INDEXES,
};
<|endoftext|>


<commit_before>// =================================================================
// Logtalk - Object oriented extension to Prolog
// Release 2.25.0
//
// Copyright (c) 1998-2005 Paulo Moura.  All Rights Reserved.
// =================================================================

WScript.Echo('');
WScript.Echo('Creating shortcuts for running Logtalk with selected Prolog compilers...');
WScript.Echo('');

var WshShell = new ActiveXObject("WScript.Shell");
var WshSystemEnv = WshShell.Environment("SYSTEM");
var WshUserEnv = WshShell.Environment("USER");

if (WshSystemEnv.Item("LOGTALKHOME"))
	logtalk_home = WshSystemEnv.Item("LOGTALKHOME");
else if (WshUserEnv.Item("LOGTALKHOME"))
	logtalk_home = WshUserEnv.Item("LOGTALKHOME")
else {
	WScript.Echo("Error! The environment variable LOGTALKHOME must be defined first!");
	usage_help();
	WScript.Quit(1);
}

WScript.Echo('Creating shortcut Logtalk - CIAO...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_ciaolgt.js", true);

WScript.Echo('Creating shortcut Logtalk - ECLiPSe...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_eclipselgt.js", true);

WScript.Echo('Creating shortcut Logtalk - GNU Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_gplgt.js", true);

WScript.Echo('Creating shortcut Logtalk - K-Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_plclgt.js", true);

WScript.Echo('Creating shortcut Logtalk - SICStus...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_sicstuslgt.js", true);

WScript.Echo('Creating shortcut Logtalk - SWI-Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_swilgt.js", true);

WScript.Echo('Creating shortcut Logtalk - YAP...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_yaplgt.js", true);

WScript.Echo('');
WScript.Echo('Done.  Links to the created scripts was been added to the Start Menu');
WScript.Echo('Programs.   Make sure that the environment variables LOGTALKHOME and');
WScript.Echo('LOGTALKUSER are defined for all users wishing to use the shortcuts.');
WScript.Echo('');
WScript.Echo('If you get an unexpected failure to create a shortcut for one of the');
WScript.Echo('above Prolog compilers, please consult the NOTES file on the scripts');
WScript.Echo('directory or try to run the corresponding script individually.');
WScript.Echo('');

WScript.Quit(0);
<commit_msg>Improved documentation.<commit_after>// =================================================================
// Logtalk - Object oriented extension to Prolog
// Release 2.25.0
//
// Copyright (c) 1998-2005 Paulo Moura.  All Rights Reserved.
// =================================================================

WScript.Echo('');
WScript.Echo('Creating shortcuts for running Logtalk with selected Prolog compilers...');
WScript.Echo('');

var WshShell = new ActiveXObject("WScript.Shell");
var WshSystemEnv = WshShell.Environment("SYSTEM");
var WshUserEnv = WshShell.Environment("USER");

if (WshSystemEnv.Item("LOGTALKHOME"))
	logtalk_home = WshSystemEnv.Item("LOGTALKHOME");
else if (WshUserEnv.Item("LOGTALKHOME"))
	logtalk_home = WshUserEnv.Item("LOGTALKHOME")
else {
	WScript.Echo("Error! The environment variable LOGTALKHOME must be defined first!");
	usage_help();
	WScript.Quit(1);
}

WScript.Echo('Creating shortcut Logtalk - CIAO...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_ciaolgt.js", true);

WScript.Echo('Creating shortcut Logtalk - ECLiPSe...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_eclipselgt.js", true);

WScript.Echo('Creating shortcut Logtalk - GNU Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_gplgt.js", true);

WScript.Echo('Creating shortcut Logtalk - K-Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_plclgt.js", true);

WScript.Echo('Creating shortcut Logtalk - SICStus...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_sicstuslgt.js", true);

WScript.Echo('Creating shortcut Logtalk - SWI-Prolog...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_swilgt.js", true);

WScript.Echo('Creating shortcut Logtalk - YAP...');
WshShell.Run("cscript %LOGTALKHOME%\\scripts\\make_yaplgt.js", true);

WScript.Echo('');
WScript.Echo('Done.  Links to the created scripts was been added to the Start Menu');
WScript.Echo('Programs.   Make sure that the environment variables LOGTALKHOME and');
WScript.Echo('LOGTALKUSER are defined for all users wishing to use the shortcuts.');
WScript.Echo('');
WScript.Echo('If you get an unexpected failure to create a shortcut for one of the');
WScript.Echo('above Prolog compilers, make sure that the Prolog compiler is properly');
WScript.Echo('installed and then consult the NOTES file on the scripts directory and');
WScript.Echo('try to run the corresponding script individually.');
WScript.Echo('');

WScript.Quit(0);
<|endoftext|>