<commit_before>#! /usr/bin/env node
// export GITHUB_TOKEN=xxx
// git config --global credential.helper osxkeychain

const asset = require("putasset"),
      release = require("grizzly"),
      shell = require("shelljs"),
      token = shell.env.GITHUB_TOKEN,
      {name, version} = JSON.parse(shell.cat("package.json"));

shell.config.silent = true;
const log = require("./log")(`release v${version}`);

let minor = version.split(".");
const prerelease = parseFloat(minor[0]) === 0;
minor = minor.slice(0, minor.length - 1).join(".");

const tests = shell.exec("d3plus-test", {silent: false});
if (tests.code) shell.exit(tests.code);

const rollup = require("./rollup");

function finishRelease() {

  log.timer("compiling examples");
  shell.exec("d3plus-examples");

  log.timer("compiling documentation");
  shell.exec("d3plus-docs");

  log.timer("compiling release notes");
  const body = shell.exec("git log --pretty=format:'* %s (%h)' `git describe --tags --abbrev=0`...HEAD").stdout;

  log.timer("publishing npm package");
  shell.exec("npm publish ./");

  log.timer("commiting all modified files for release");
  const add = shell.exec("git add --all");
  if (add.code) {
    log.fail();
    shell.exit(add.code);
  }
  const commit = shell.exec(`git commit -m \"compiles v${version}\"`);
  if (commit.code) {
    log.fail();
    shell.exit(commit.code);
  }

  log.timer("pushing to repository");
  const push = shell.exec("git push -q");
  if (push.code) {
    log.fail();
    shell.exit(push.code);
  }

  log.timer("tagging latest commit");
  shell.exec(`git tag v${version}`);
  shell.exec("git push -q --tags");

  log.timer("publishing release notes");
  release(token, {
    repo: name,
    user: "d3plus",
    tag: `v${version}`,
    name: `v${version}`,
    body, prerelease
  }, error => {
    if (error) {
      log.fail();
      shell.echo(error.message);
      shell.exit(1);
    }
    else {

      if (shell.test("-f", `build/${name}.zip`)) {
        log.timer("attaching .zip distribution to release");
        asset(token, {
          repo: name,
          owner: "d3plus",
          tag: `v${version}`,
          filename: `build/${name}.zip`
        }, error => {
          if (error) {
            log.fail();
            shell.echo(error.message);
            shell.exit(1);
          }
          else {
            log.done();
            shell.exit(0);
          }
        });
      }
      else {
        log.done();
        shell.exit(0);
      }

    }
  });

}

if (shell.test("-d", "src")) {

  rollup().then(() => {
    rollup({deps: true}).then(() => {

      log.timer("uglify builds");
      shell.exec(`uglifyjs build/${name}.js -m --comments -o build/${name}.min.js`);
      shell.exec(`uglifyjs build/${name}.full.js -m --comments -o build/${name}.full.min.js`);

      log.timer("create .zip distribution");
      shell.exec(`rm -f build/${name}.zip && zip -j -q build/${name}.zip -- LICENSE README.md build/${name}.js build/${name}.min.js build/${name}.full.js build/${name}.full.min.js`);

      if (shell.test("-d", "../d3plus-website")) {
        log.timer("uploading builds to d3plus.org");
        shell.cp(`build/${name}.js`, `../d3plus-website/js/${name}.v${minor}.js`);
        shell.cp(`build/${name}.full.js`, `../d3plus-website/js/${name}.v${minor}.full.js`);
        shell.cp(`build/${name}.min.js`, `../d3plus-website/js/${name}.v${minor}.min.js`);
        shell.cp(`build/${name}.full.min.js`, `../d3plus-website/js/${name}.v${minor}.full.min.js`);
        shell.cd("../d3plus-website");
        shell.exec(`git add js/${name}.v${minor}.js js/${name}.v${minor}.min.js js/${name}.v${minor}.full.js js/${name}.v${minor}.full.min.js`);
        shell.exec(`git commit -m \"${name} v${version}\"`);
        shell.exec("git push -q");
        shell.cd("-");
      }
      else {
        log.done();
        log.warn("d3plus-website repository folder not found in parent directory, builds cannot be uploaded to d3plus.org");
      }

      finishRelease();

    });
  });

}
else finishRelease();
<commit_msg>adds more robust error reporting with release not publish<commit_after>#! /usr/bin/env node
// export GITHUB_TOKEN=xxx
// git config --global credential.helper osxkeychain

const asset = require("putasset"),
      release = require("grizzly"),
      shell = require("shelljs"),
      token = shell.env.GITHUB_TOKEN,
      {name, version} = JSON.parse(shell.cat("package.json"));

shell.config.silent = true;
const log = require("./log")(`release v${version}`);

let minor = version.split(".");
const prerelease = parseFloat(minor[0]) === 0;
minor = minor.slice(0, minor.length - 1).join(".");

const tests = shell.exec("d3plus-test", {silent: false});
if (tests.code) shell.exit(tests.code);

const rollup = require("./rollup");

function finishRelease() {

  log.timer("compiling examples");
  shell.exec("d3plus-examples");

  log.timer("compiling documentation");
  shell.exec("d3plus-docs");

  log.timer("compiling release notes");
  const body = shell.exec("git log --pretty=format:'* %s (%h)' `git describe --tags --abbrev=0`...HEAD").stdout;

  log.timer("publishing npm package");
  shell.exec("npm publish ./");

  log.timer("commiting all modified files for release");
  const add = shell.exec("git add --all");
  if (add.code) {
    log.fail();
    shell.exit(add.code);
  }
  const commit = shell.exec(`git commit -m \"compiles v${version}\"`);
  if (commit.code) {
    log.fail();
    shell.exit(commit.code);
  }

  log.timer("pushing to repository");
  const push = shell.exec("git push -q");
  if (push.code) {
    log.fail();
    shell.exit(push.code);
  }

  log.timer("tagging latest commit");
  shell.exec(`git tag v${version}`);
  shell.exec("git push -q --tags");

  log.timer("publishing release notes");
  release(token, {
    repo: name,
    user: "d3plus",
    tag: `v${version}`,
    name: `v${version}`,
    body, prerelease
  }, error => {
    if (error) {
      log.fail();
      shell.echo(`repo: ${name}`);
      shell.echo(`tag/name: v${version}`);
      shell.echo(`body: ${body}`);
      shell.echo(`prerelease: ${prerelease}`);
      shell.echo(error.message);
      shell.exit(1);
    }
    else {

      if (shell.test("-f", `build/${name}.zip`)) {
        log.timer("attaching .zip distribution to release");
        asset(token, {
          repo: name,
          owner: "d3plus",
          tag: `v${version}`,
          filename: `build/${name}.zip`
        }, error => {
          if (error) {
            log.fail();
            shell.echo(error.message);
            shell.exit(1);
          }
          else {
            log.done();
            shell.exit(0);
          }
        });
      }
      else {
        log.done();
        shell.exit(0);
      }

    }
  });

}

if (shell.test("-d", "src")) {

  rollup().then(() => {
    rollup({deps: true}).then(() => {

      log.timer("uglify builds");
      shell.exec(`uglifyjs build/${name}.js -m --comments -o build/${name}.min.js`);
      shell.exec(`uglifyjs build/${name}.full.js -m --comments -o build/${name}.full.min.js`);

      log.timer("create .zip distribution");
      shell.exec(`rm -f build/${name}.zip && zip -j -q build/${name}.zip -- LICENSE README.md build/${name}.js build/${name}.min.js build/${name}.full.js build/${name}.full.min.js`);

      if (shell.test("-d", "../d3plus-website")) {
        log.timer("uploading builds to d3plus.org");
        shell.cp(`build/${name}.js`, `../d3plus-website/js/${name}.v${minor}.js`);
        shell.cp(`build/${name}.full.js`, `../d3plus-website/js/${name}.v${minor}.full.js`);
        shell.cp(`build/${name}.min.js`, `../d3plus-website/js/${name}.v${minor}.min.js`);
        shell.cp(`build/${name}.full.min.js`, `../d3plus-website/js/${name}.v${minor}.full.min.js`);
        shell.cd("../d3plus-website");
        shell.exec(`git add js/${name}.v${minor}.js js/${name}.v${minor}.min.js js/${name}.v${minor}.full.js js/${name}.v${minor}.full.min.js`);
        shell.exec(`git commit -m \"${name} v${version}\"`);
        shell.exec("git push -q");
        shell.cd("-");
      }
      else {
        log.done();
        log.warn("d3plus-website repository folder not found in parent directory, builds cannot be uploaded to d3plus.org");
      }

      finishRelease();

    });
  });

}
else finishRelease();
<|endoftext|>


<commit_before>#! /usr/bin/env node

var program = require('starting');
var path = require('path');
var config = require('../package.json');
var util = require('../util');
var CONFIG_DIR = util.LOCAL_DATA_PATH;

util.mkdir(CONFIG_DIR);

program.setConfig({
	main: path.join(__dirname, '../index.js'),
	running: path.join(CONFIG_DIR, '.running'),
	name: config.name,
	version: config.version,
	runCallback: function() {
		console.log('[i] Press [Ctrl+C] to stop %s...', config.name);
		console.log('[i] visit http://' + config.localUIHost + '/ to get started');
	},
	startCallback: function(alreadyInRunning) {
		console.log('[!] ' + config.name + ( alreadyInRunning ? ' is running.' : ' started.'));
		console.log('[i] visit http://' + config.localUIHost + '/ to get started');
	},
	restartCallback: function() {
		console.log('[!] %s started.', config.name);
	},
	stopCallback: function(err) {
		if (err === true) {
			console.log('[i] %s killed.', config.name);
		} else if (err) {
				err.code === 'EPERM' ? console.log('[!] Cannot kill %s owned by root.\n' +
					'    Try to run command with `sudo`.', config.name)
				: console.log('[!] %s', err.message);
		} else {
			console.log('[!] No running %s.', config.name);
		}
	}
});

program
	.option('-r, --rules [rule file path]', 'rules file', String, undefined)
	.option('-n, --username [username]', 'login username', String, undefined)
	.option('-w, --password [password]', 'login password', String, undefined)
	.option('-p, --port [port]', config.name + ' port(' + config.port + ' by default)', parseInt, undefined)
	.option('-m, --middlewares [script path or module name]', 'express middlewares path (as: xx,yy/zz.js)', String, undefined)
	.option('-u, --uipath [script path]', 'web ui plugin path', String, undefined)
	.option('-t, --timneout [ms]', 'request timeout(' + config.timeout + ' ms by default)', parseInt, undefined)
	.option('-s, --sockets [number]', 'max sockets', parseInt, undefined)
	.option('-d, --days [number]', 'the maximum days of cache', parseInt, undefined)
	.parse(process.argv);<commit_msg>remove cache time<commit_after>#! /usr/bin/env node

var program = require('starting');
var path = require('path');
var config = require('../package.json');
var util = require('../util');
var CONFIG_DIR = util.LOCAL_DATA_PATH;

util.mkdir(CONFIG_DIR);

program.setConfig({
	main: path.join(__dirname, '../index.js'),
	running: path.join(CONFIG_DIR, '.running'),
	name: config.name,
	version: config.version,
	runCallback: function() {
		console.log('[i] Press [Ctrl+C] to stop %s...', config.name);
		console.log('[i] visit http://' + config.localUIHost + '/ to get started');
	},
	startCallback: function(alreadyInRunning) {
		console.log('[!] ' + config.name + ( alreadyInRunning ? ' is running.' : ' started.'));
		console.log('[i] visit http://' + config.localUIHost + '/ to get started');
	},
	restartCallback: function() {
		console.log('[!] %s started.', config.name);
	},
	stopCallback: function(err) {
		if (err === true) {
			console.log('[i] %s killed.', config.name);
		} else if (err) {
				err.code === 'EPERM' ? console.log('[!] Cannot kill %s owned by root.\n' +
					'    Try to run command with `sudo`.', config.name)
				: console.log('[!] %s', err.message);
		} else {
			console.log('[!] No running %s.', config.name);
		}
	}
});

program
	.option('-r, --rules [rule file path]', 'rules file', String, undefined)
	.option('-n, --username [username]', 'login username', String, undefined)
	.option('-w, --password [password]', 'login password', String, undefined)
	.option('-p, --port [port]', config.name + ' port(' + config.port + ' by default)', parseInt, undefined)
	.option('-m, --middlewares [script path or module name]', 'express middlewares path (as: xx,yy/zz.js)', String, undefined)
	.option('-u, --uipath [script path]', 'web ui plugin path', String, undefined)
	.option('-t, --timneout [ms]', 'request timeout(' + config.timeout + ' ms by default)', parseInt, undefined)
	.option('-s, --sockets [number]', 'max sockets', parseInt, undefined)
	.parse(process.argv);<|endoftext|>


<commit_before><commit_msg>reformatted library<commit_after><|endoftext|>


<commit_before>/**
 * Oy:
 * Exposes `renderTemplate` functionality, along with `Mixin` and `rule`.
 * A base template to build emails with.
 *
 * Based on guidelines here:
 * https://github.com/centralcollegenottingham/HTML-Email-Boilerplate-Redux/blob/master/htmlemail-boilerplate-stable-with-guidelines.html
 */

import HTML4 from './utils/HTML4';

import OyElement from './components/OyElement';

export default {
  Element: OyElement,

  PropTypes: {
    rules: (ruleNames) => {
      return (props, propName, componentName) => {
        return ruleNames
          .map((ruleName) => require(`./rules/${ruleName}`)(props, propName, componentName))
          .filter((error) => error instanceof Error)
          [0];
      };
    }
  },

  renderTemplate: (options) => {
    [
      'title',
      'bodyContent',
      'previewText'
    ].forEach((option) => {
      if (!options[option]) {
        throw new Error(`'${option}' is a required option in the object used in 'renderTemplate'`);
      }
    });

    const title = options.title;
    const bodyContent = options.bodyContent || '';
    const headCSS = options.headCSS || '';
    const previewText = options.previewText || '';

    const rawHTML = `
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width"/>

          <title>${title}</title>

                ${previewText}
                ${bodyContent}

    `;

    return HTML4.replaceWhitelistedAttributes(rawHTML);
  }
};
<commit_msg>support custom validators<commit_after>/**
 * Oy:
 * Exposes `renderTemplate` functionality, along with `Mixin` and `rule`.
 * A base template to build emails with.
 *
 * Based on guidelines here:
 * https://github.com/centralcollegenottingham/HTML-Email-Boilerplate-Redux/blob/master/htmlemail-boilerplate-stable-with-guidelines.html
 */

import HTML4 from './utils/HTML4';

import OyElement from './components/OyElement';

export default {
  Element: OyElement,

  PropTypes: {
    rules: (ruleNames) => {
      return (props, propName, componentName) => {
        return ruleNames
          .map((ruleName) => {
            if (typeof ruleName === 'string' || ruleName instanceof String) {
              return require(`./rules/${ruleName}`)(props, propName, componentName);
            } else {
              return ruleName;
            }
          })
          .filter((error) => error instanceof Error)
          [0];
      };
    }
  },

  renderTemplate: (options) => {
    [
      'title',
      'bodyContent',
      'previewText'
    ].forEach((option) => {
      if (!options[option]) {
        throw new Error(`'${option}' is a required option in the object used in 'renderTemplate'`);
      }
    });

    const title = options.title;
    const bodyContent = options.bodyContent || '';
    const headCSS = options.headCSS || '';
    const previewText = options.previewText || '';

    const rawHTML = `
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

          <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width"/>

          <title>${title}</title>

                ${previewText}
                ${bodyContent}

    `;

    return HTML4.replaceWhitelistedAttributes(rawHTML);
  }
};
<|endoftext|>


<commit_before>(function ( window ) {
    'use strict';
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB,
        IDBDatabase = window.IDBDatabase || window.webkitIDBDatabase,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var oldApi = !!IDBDatabase.prototype.setVersion;

    if ( !indexedDB ) {
        throw 'IndexedDB required';
    }

    var CallbackList = function () {
        var state,
            list = [];

        var exec = function ( context , args ) {
            if ( list ) {
                args = args || [];
                state = state || [ context , args ];

                for ( var i = 0 , il = list.length ; i < il ; i++ ) {
                    list[ i ].apply( state[ 0 ] , state[ 1 ] );
                }

                list = [];
            }
        };

        this.add = function () {
            for ( var i = 0 , il = arguments.length ; i < il ; i ++ ) {
                list.push( arguments[ i ] );
            }

            if ( state ) {
                exec();
            }

            return this;
        };

        this.execute = function () {
            exec( this , arguments );
            return this;
        };
    };

    var Promise = function () {
        var doneList = new CallbackList(),
            failedList = new CallbackList(),
            progressList = new CallbackList(),
            state = 'progress';

        this.done = doneList.add;
        this.fail = failedList.add;
        this.progress = progressList.add;
        this.resolve = doneList.execute;
        this.reject = failedList.execute;
        this.notify = progressList.execute;

        this.then = function ( doneHandler , failedHandler , progressHandler ) {
            return this.done( doneHandler ).fail( failedHandler ).progress( progressHandler );
        };

        this.done( function () {
            state = 'resolved';
        }).fail( function () {
            state = 'rejected';
        });
    };

    var Server = function ( db , name ) {
        var that = this,
            closed = false;

        this.add = function( table , records ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            if ( records.constructor !== Array ) {
                records = [ records ];
            }

            records.forEach( function ( record ) {
                var req = store.add( record );
                req.onsuccess = function ( e ) {
                    var target = e.target;
                    record[ target.source.keyPath ] = target.result;
                    promise.notify();
                };
            } );

            transaction.oncomplete = function () {
                promise.resolve( records , that );
            };
            transaction.onerror = function ( e ) {
                promise.reject( records , e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( records , e );
            };
            return promise;
        };

        this.remove = function ( table , key ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.delete( key );
            req.onsuccess = function ( e ) {
                promise.resolve( key );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.query = function ( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new Query( table , db );
        };

        this.close = function ( ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[ name ];
        };

        this.get = function ( table , id ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.get( id );
            req.onsuccess = function ( e ) {
                promise.resolve( e.target.result );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.index = function ( table , index ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new IndexQuery( table , index , db );
        };

        for ( var i = 0 , il = db.objectStoreNames.length ; i < il ; i++ ) {
            (function ( storeName ) {
                that[ storeName ] = { };
                for ( var i in that ) {
                    if ( !hasOwn.call( that , i ) || i === 'close' ) {
                        continue;
                    }
                    that[ storeName ][ i ] = (function ( i ) {
                        return function () {
                            var args = [ storeName ].concat( [].slice.call( arguments , 0 ) );
                            return that[ i ].apply( that , args );
                        };
                    })( i );
                }
            })( db.objectStoreNames[ i ] );
        }
    };

    var IndexQuery = function ( table , indexName , db ) {
        var runQuery = function ( type, args , cursorType ) {
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                index = store.index( indexName ),
                keyRange = IDBKeyRange[type].apply( null, args ),
                results = [],
                promise = new Promise();

            index[cursorType]( keyRange ).onsuccess = function ( e ) {
                var cursor = e.target.result;

                if ( typeof cursor === typeof 0 ) {
                    results = cursor;
                } else if ( cursor ) {
                    results.push( 'value' in cursor ? cursor.value : cursor.key );
                    cursor.continue();
                }
            };

            transaction.oncomplete = function () {
                promise.resolve( results );
            };
            transaction.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        var Query = function ( type , args ) {
            return {
                execute: function () {
                    return runQuery( type , args , 'openCursor' );
                },
                count: function () {
                    return runQuery( type , args , 'count' );
                },
                keys: function () {
                    return runQuery( type , args , 'openKeyCursor' );
                }
            }
        };

        this.only = function () {
            return new Query( 'only' , arguments );
        };

        this.bound = function () {
            return new Query( 'bound' , arguments );
        };

        this.upperBound = function () {
            return new Query( 'upperBound' , arguments );
        };

        this.lowerBound = function () {
            return new Query( 'lowerBound' , arguments );
        };
    };

    var Query = function ( table , db ) {
        var that = this,
            filters = [];

        this.filter = function ( field , value ) {
            filters.push( {
                field: field,
                value: value
            });
            return that;
        };

        this.execute = function () {
            var records = [],
                transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                req = store.openCursor(),
                promise = new Promise();

            req.onsuccess = function ( e ) {
                var value, f,
                    inc = true,
                    cursor = e.target.result;

                if ( cursor ) {
                    value = cursor.value;
                    for ( var i = 0 , il = filters.length ; i < il ; i++ ) {
                        f = filters[ i ];
                        if (typeof f.field === 'function') {
                            inc = f.field(value);
                        } else if (value[f.field] !== f.value) {
                            inc = false;
                        }
                    }

                    if ( inc ) {
                        records.push( value );
                    } else {
                        if ( ~records.indexOf( value ) ) {
                            records = records.slice( 0 , records.indexOf( value ) ).concat( records.indexOf( value ) );
                        }
                    }

                    cursor.continue();
                } else {
                    promise.resolve( records );
                }
            };

            req.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };

            return promise;
        };
    };

    var createSchema = function ( e , schema , db ) {
        if ( typeof schema === 'function' ) {
            schema = schema();
        }

        for ( var tableName in schema ) {
            var table = schema[ tableName ];
            if ( !hasOwn.call( schema , tableName ) ) {
                continue;
            }

            var store = db.createObjectStore( tableName , table.key );

            for ( var indexKey in table.indexes ) {
                var index = table.indexes[ indexKey ];
                store.createIndex( indexKey , index.key || indexKey , index.options || { unique: false } );
            }
        }
    };

    var open = function ( e , server , version , schema ) {
        var db = e.target.result;
        var s = new Server( db , server );
        var upgrade;

        var promise = new Promise();

        if ( oldApi && window.parseInt( db.version ) !== version ) {
            upgrade = db.setVersion( version );

            upgrade.onsuccess = function ( e ) {
                createSchema( e , schema , db );

                promise.resolve( s );
            };
            upgrade.onerror = function ( e ) {
                promise.reject( e );
            };

            upgrade.onblocked = function () {
                promise.reject( e );
            };
        } else {
            promise.resolve( s );
        }
        dbCache[ server ] = db;

        return promise;
    };

    var dbCache = {};

    window.db = {
        open: function ( options ) {
            var request;

            var promise = new Promise();

            if ( dbCache[ options.server ] ) {
                open( {
                    target: {
                        result: dbCache[ options.server ]
                    }
                } , options.server , options.version , options.schema )
                .done(promise.resolve)
                .fail(promise.reject)
                .progress(promise.notify);
            } else {
                request = indexedDB.open( options.server , options.version );

                request.onsuccess = function ( e ) {
                    open( e , options.server , options.version , options.schema )
                        .done(promise.resolve)
                        .fail(promise.reject)
                        .progress(promise.notify);
                };

                request.onupgradeneeded = function ( e ) {
                    createSchema( e , options.schema , e.target.result );
                };
                request.onerror = function ( e ) {
                    promise.reject( e );
                };
            }

            return promise;
        }
    };
})( window );
<commit_msg>cleaner way to create each query type<commit_after>(function ( window ) {
    'use strict';
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB,
        IDBDatabase = window.IDBDatabase || window.webkitIDBDatabase,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var oldApi = !!IDBDatabase.prototype.setVersion;

    if ( !indexedDB ) {
        throw 'IndexedDB required';
    }

    var CallbackList = function () {
        var state,
            list = [];

        var exec = function ( context , args ) {
            if ( list ) {
                args = args || [];
                state = state || [ context , args ];

                for ( var i = 0 , il = list.length ; i < il ; i++ ) {
                    list[ i ].apply( state[ 0 ] , state[ 1 ] );
                }

                list = [];
            }
        };

        this.add = function () {
            for ( var i = 0 , il = arguments.length ; i < il ; i ++ ) {
                list.push( arguments[ i ] );
            }

            if ( state ) {
                exec();
            }

            return this;
        };

        this.execute = function () {
            exec( this , arguments );
            return this;
        };
    };

    var Promise = function () {
        var doneList = new CallbackList(),
            failedList = new CallbackList(),
            progressList = new CallbackList(),
            state = 'progress';

        this.done = doneList.add;
        this.fail = failedList.add;
        this.progress = progressList.add;
        this.resolve = doneList.execute;
        this.reject = failedList.execute;
        this.notify = progressList.execute;

        this.then = function ( doneHandler , failedHandler , progressHandler ) {
            return this.done( doneHandler ).fail( failedHandler ).progress( progressHandler );
        };

        this.done( function () {
            state = 'resolved';
        }).fail( function () {
            state = 'rejected';
        });
    };

    var Server = function ( db , name ) {
        var that = this,
            closed = false;

        this.add = function( table , records ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            if ( records.constructor !== Array ) {
                records = [ records ];
            }

            records.forEach( function ( record ) {
                var req = store.add( record );
                req.onsuccess = function ( e ) {
                    var target = e.target;
                    record[ target.source.keyPath ] = target.result;
                    promise.notify();
                };
            } );

            transaction.oncomplete = function () {
                promise.resolve( records , that );
            };
            transaction.onerror = function ( e ) {
                promise.reject( records , e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( records , e );
            };
            return promise;
        };

        this.remove = function ( table , key ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.delete( key );
            req.onsuccess = function ( e ) {
                promise.resolve( key );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.query = function ( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new Query( table , db );
        };

        this.close = function ( ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[ name ];
        };

        this.get = function ( table , id ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.get( id );
            req.onsuccess = function ( e ) {
                promise.resolve( e.target.result );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.index = function ( table , index ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new IndexQuery( table , index , db );
        };

        for ( var i = 0 , il = db.objectStoreNames.length ; i < il ; i++ ) {
            (function ( storeName ) {
                that[ storeName ] = { };
                for ( var i in that ) {
                    if ( !hasOwn.call( that , i ) || i === 'close' ) {
                        continue;
                    }
                    that[ storeName ][ i ] = (function ( i ) {
                        return function () {
                            var args = [ storeName ].concat( [].slice.call( arguments , 0 ) );
                            return that[ i ].apply( that , args );
                        };
                    })( i );
                }
            })( db.objectStoreNames[ i ] );
        }
    };

    var IndexQuery = function ( table , indexName , db ) {
        var that = this;
        var runQuery = function ( type, args , cursorType ) {
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                index = store.index( indexName ),
                keyRange = IDBKeyRange[type].apply( null, args ),
                results = [],
                promise = new Promise();

            index[cursorType]( keyRange ).onsuccess = function ( e ) {
                var cursor = e.target.result;

                if ( typeof cursor === typeof 0 ) {
                    results = cursor;
                } else if ( cursor ) {
                    results.push( 'value' in cursor ? cursor.value : cursor.key );
                    cursor.continue();
                }
            };

            transaction.oncomplete = function () {
                promise.resolve( results );
            };
            transaction.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        var Query = function ( type , args ) {
            return {
                execute: function () {
                    return runQuery( type , args , 'openCursor' );
                },
                count: function () {
                    return runQuery( type , args , 'count' );
                },
                keys: function () {
                    return runQuery( type , args , 'openKeyCursor' );
                }
            }
        };

        'only bound upperBound lowerBound'.split(' ').forEach(function (name) {
            that[name] = function () {
                return new Query( name , arguments );
            };
        });
    };

    var Query = function ( table , db ) {
        var that = this,
            filters = [];

        this.filter = function ( field , value ) {
            filters.push( {
                field: field,
                value: value
            });
            return that;
        };

        this.execute = function () {
            var records = [],
                transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                req = store.openCursor(),
                promise = new Promise();

            req.onsuccess = function ( e ) {
                var value, f,
                    inc = true,
                    cursor = e.target.result;

                if ( cursor ) {
                    value = cursor.value;
                    for ( var i = 0 , il = filters.length ; i < il ; i++ ) {
                        f = filters[ i ];
                        if (typeof f.field === 'function') {
                            inc = f.field(value);
                        } else if (value[f.field] !== f.value) {
                            inc = false;
                        }
                    }

                    if ( inc ) {
                        records.push( value );
                    } else {
                        if ( ~records.indexOf( value ) ) {
                            records = records.slice( 0 , records.indexOf( value ) ).concat( records.indexOf( value ) );
                        }
                    }

                    cursor.continue();
                } else {
                    promise.resolve( records );
                }
            };

            req.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };

            return promise;
        };
    };

    var createSchema = function ( e , schema , db ) {
        if ( typeof schema === 'function' ) {
            schema = schema();
        }

        for ( var tableName in schema ) {
            var table = schema[ tableName ];
            if ( !hasOwn.call( schema , tableName ) ) {
                continue;
            }

            var store = db.createObjectStore( tableName , table.key );

            for ( var indexKey in table.indexes ) {
                var index = table.indexes[ indexKey ];
                store.createIndex( indexKey , index.key || indexKey , index.options || { unique: false } );
            }
        }
    };

    var open = function ( e , server , version , schema ) {
        var db = e.target.result;
        var s = new Server( db , server );
        var upgrade;

        var promise = new Promise();

        if ( oldApi && window.parseInt( db.version ) !== version ) {
            upgrade = db.setVersion( version );

            upgrade.onsuccess = function ( e ) {
                createSchema( e , schema , db );

                promise.resolve( s );
            };
            upgrade.onerror = function ( e ) {
                promise.reject( e );
            };

            upgrade.onblocked = function () {
                promise.reject( e );
            };
        } else {
            promise.resolve( s );
        }
        dbCache[ server ] = db;

        return promise;
    };

    var dbCache = {};

    window.db = {
        open: function ( options ) {
            var request;

            var promise = new Promise();

            if ( dbCache[ options.server ] ) {
                open( {
                    target: {
                        result: dbCache[ options.server ]
                    }
                } , options.server , options.version , options.schema )
                .done(promise.resolve)
                .fail(promise.reject)
                .progress(promise.notify);
            } else {
                request = indexedDB.open( options.server , options.version );

                request.onsuccess = function ( e ) {
                    open( e , options.server , options.version , options.schema )
                        .done(promise.resolve)
                        .fail(promise.reject)
                        .progress(promise.notify);
                };

                request.onupgradeneeded = function ( e ) {
                    createSchema( e , options.schema , e.target.result );
                };
                request.onerror = function ( e ) {
                    promise.reject( e );
                };
            }

            return promise;
        }
    };
})( window );
<|endoftext|>


<commit_before>//Copyright 2014, Small Picture, Inc.
	//1/19/14 by DW
		//This is a shell for developing the functionality of the Fargo back-end.
		//When done, it will take requests saying that a named outline has updated.
		//It will know how to find the OPML, and from there, to find a "package" of updates.
		//Which it will then parse, and upload to a bucket on S3.
		//Still have a ways to go, but it's fun, and a lot is working! :-)

var http = require ("http");
var urlpack = require ("url");
var AWS = require ("aws-sdk");
var s3 = new AWS.S3 ();

var httpReadUrl = function (url, callback) {
	var httpoptions, httptext = "", httpmethod = "GET";
	//set httpoptions with info from url
		var x = urlpack.parse (url);
		if (x.port == null) {
			x.port = "80";
			}
		httpoptions = {
			host: x.host,
			port: x.port,
			path: x.path,
			method: httpmethod
			};
	var req = http.request (httpoptions, function (res) {
		res.setEncoding ("utf8");
		res.on ("data", function (chunk) {
			httptext += chunk;
			});
		res.on ("end", function () {
			callback (httptext);
			});
		});
	req.on ("error", function (e) {
		console.log ("httpReadUrl error: " + e.message);
		});
	req.end ();
	}
var padWithZeros = function (num, ctplaces) {
	var s = num.toString ();
	while (s.length < ctplaces) {
		s = "0" + s;
		}
	return (s);
	}
var isAlpha = function (ch) {
	return (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')));
	}
var handlePackagePing = function (urloutline) {
	console.log ("handlePackagePing: " + urloutline);
	}

var writeStaticFile = function (path, data, type, acl) {
	var bucketname = "";
	if (type == undefined) {
		type = "text/plain";
		}
	if (acl == undefined) {
		acl = "public-read";
		}

	//split path into bucketname and path -- like this: /tmp.scripting.com/testing/one.txt
		if (path.length > 0) {
			if (path [0] == "/") { //delete the slash
				path = path.substr (1);
				}
			var ix = path.indexOf ("/");
			bucketname = path.substr (0, ix);
			path = path.substr (ix + 1);
			}

	var params = {
		ACL: acl,
		ContentType: type,
		Body: data,
		Bucket: bucketname,
		Key: path
		};
	s3.putObject (params, function (err, data) {
		console.log ("Wrote: http://" + bucketname + "/" + path);
		httpReadUrl ("http://" + bucketname + "/" + path, function (s) {
			console.log ("httpReadUrl: " + s + ".");
			});
		});
	}

console.log ("starting server");
var counter = 0;
var server = http.createServer (function (request, response) {
	console.log (request.url);

	var parsedUrl = urlpack.parse (request.url, true);

	switch (parsedUrl.pathname.toLowerCase ()) {
		case "/":
			response.writeHead (200, {"Content-Type": "text/plain"});
			var color = 'blue';
			if (counter % 2 === 1) {
				color = 'no, green';
				}
			response.end (color);
			writeStaticFile ("/tmp.scripting.com/testing/" + padWithZeros (counter, 4) + ".txt", new Date ().toString ());
			counter++;
			break;
		case "/pingpackage":
			response.writeHead (200, {"Content-Type": "text/plain"});
			handlePackagePing (parsedUrl.query.link);
			response.end ("Oh the buzzing of the bees and the sycamore trees. A soda water fountain!");
			break;
		default:
			response.writeHead (404, {"Content-Type": "text/plain"});
			response.end ("404 Not Found");
			break;
		}
	});
server.listen (1337);
<commit_msg>Update<commit_after>//Copyright 2014, Small Picture, Inc.
	//1/19/14 by DW
		//This is a shell for developing the functionality of the Fargo back-end.
		//When done, it will take requests saying that a named outline has updated.
		//It will know how to find the OPML, and from there, to find a "package" of updates.
		//Which it will then parse, and upload to a bucket on S3.
		//Still have a ways to go, but it's fun, and a lot is working! :-)

var http = require ("http");
var urlpack = require ("url");
var AWS = require ("aws-sdk");
var s3 = new AWS.S3 ();

var httpReadUrl = function (url, callback) {
	var httpoptions, httptext = "", httpmethod = "GET";
	//set httpoptions with info from url
		var x = urlpack.parse (url);
		if (x.port == null) {
			x.port = "80";
			}
		httpoptions = {
			host: x.host,
			port: x.port,
			path: x.path,
			method: httpmethod
			};
	var req = http.request (httpoptions, function (res) {
		res.setEncoding ("utf8");
		res.on ("data", function (chunk) {
			httptext += chunk;
			});
		res.on ("end", function () {
			callback (httptext);
			});
		});
	req.on ("error", function (e) {
		console.log ("httpReadUrl error: " + e.message);
		});
	req.end ();
	}
var padWithZeros = function (num, ctplaces) {
	var s = num.toString ();
	while (s.length < ctplaces) {
		s = "0" + s;
		}
	return (s);
	}
var isAlpha = function (ch) {
	return (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')));
	}
var handlePackagePing = function (urloutline) {
	console.log ("handlePackagePing: " + urloutline);
	}

var writeStaticFile = function (path, data, type, acl) {
	var bucketname = "";
	if (type == undefined) {
		type = "text/plain";
		}
	if (acl == undefined) {
		acl = "public-read";
		}

	//split path into bucketname and path -- like this: /tmp.scripting.com/testing/one.txt
		if (path.length > 0) {
			if (path [0] == "/") { //delete the slash
				path = path.substr (1);
				}
			var ix = path.indexOf ("/");
			bucketname = path.substr (0, ix);
			path = path.substr (ix + 1);
			}

	var params = {
		ACL: acl,
		ContentType: type,
		Body: data,
		Bucket: bucketname,
		Key: path
		};
	s3.putObject (params, function (err, data) {
		console.log ("Wrote: http://" + bucketname + "/" + path);
		httpReadUrl ("http://" + bucketname + "/" + path, function (s) {
			console.log ("httpReadUrl: " + s + ".");
			});
		});
	}

console.log ("starting server");
var counter = 0;
var server = http.createServer (function (request, response) {
	console.log (request.url);

	var parsedUrl = urlpack.parse (request.url, true);

	switch (parsedUrl.pathname.toLowerCase ()) {
		case "/":
			response.writeHead (200, {"Content-Type": "text/plain"});
			var color = 'blue';
			if (counter % 2 === 1) {
				color = 'no, green';
				}
			response.end (color);
			writeStaticFile ("/tmp.scripting.com/testing/" + padWithZeros (counter, 4) + ".txt", new Date ().toString ());
			counter++;
			break;
		case "/pingpackage":
			response.writeHead (200, {"Content-Type": "application/json"});
			handlePackagePing (parsedUrl.query.link);

			var struct = {"url": parsedUrl.query.link)};
			var s = "getData (" + JSON.stringify (struct) + ")");
			response.end (s);

			break;
		default:
			response.writeHead (404, {"Content-Type": "text/plain"});
			response.end ("404 Not Found");
			break;
		}
	});
server.listen (1337);
<|endoftext|>


<commit_before>"use strict";

// Use the fastest means possible to execute a task in its own turn, with
// priority over other events including IO, animation, reflow, and redraw
// events in browsers.
//
// An exception thrown by a task will permanently interrupt the processing of
// subsequent tasks. The higher level `asap` function ensures that if an
// exception is thrown by a task, that the task queue will continue flushing as
// soon as possible, but if you use `rawAsap` directly, you are responsible to
// either ensure that no exceptions are thrown from your task, or to manually
// call `rawAsap.requestFlush` if an exception is thrown.
module.exports = rawAsap;
function rawAsap(task) {
    if (!queue.length) {
        requestFlush();
        flushing = true;
    }
    // Equivalent to push, but avoids a function call.
    queue[queue.length] = task;
}

var queue = [];
// Once a flush has been requested, no further calls to `requestFlush` are
// necessary until the next `flush` completes.
var flushing = false;
// `requestFlush` is an implementation-specific method that attempts to kick
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
// the event queue before yielding to the browser's own event loop.
var requestFlush;
// The position of the next task to execute in the task queue. This is
// preserved between calls to `flush` so that it can be resumed if
// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grow
// unbounded. To prevent memory exhaustion, the task queue will periodically
// truncate already-completed tasks.
var capacity = 1024;

// The flush function processes all tasks that have been scheduled with
// `rawAsap` unless and until one of those tasks throws an exception.
// If a task throws an exception, `flush` ensures that its state will remain
// consistent and will resume where it left off when called again.
// However, `flush` does not make any arrangements to be called again if an
// exception is thrown.
function flush() {
    while (index < queue.length) {
        var currentIndex = index;
        // Advance the index before calling the task. This ensures that we will
        // begin flushing on the next task the task throws an error.
        index = index + 1;
        queue[currentIndex].call();
        // Prevent leaking memory for long chains of recursive calls to `asap`.
        // If we call `asap` within tasks scheduled by `asap`, the queue will
        // grow, but to avoid an O(n) walk for every task we execute, we don't
        // shift tasks off the queue after they have been executed.
        // Instead, we periodically shift 1024 tasks off the queue.
        if (index > capacity) {
            // Manually shift all values starting at the index back to the
            // beginning of the queue.
            for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
                queue[scan] = queue[scan + index];
            }
            queue.length -= index;
            index = 0;
        }
    }
    queue.length = 0;
    index = 0;
    flushing = false;
}

// `requestFlush` is implemented using a strategy based on data collected from
// every available SauceLabs Selenium web driver worker at time of writing.
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593

// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
// have WebKitMutationObserver but not un-prefixed MutationObserver.
// Must use `global` instead of `window` to work in both frames and web
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
var BrowserMutationObserver = global.MutationObserver || global.WebKitMutationObserver;

// MutationObservers are desirable because they have high priority and work
// reliably everywhere they are implemented.
// They are implemented in all modern browsers.
//
// - Android 4-4.3
// - Chrome 26-34
// - Firefox 14-29
// - Internet Explorer 11
// - iPad Safari 6-7.1
// - iPhone Safari 7-7.1
// - Safari 6-7
if (typeof BrowserMutationObserver === "function") {
    requestFlush = makeRequestCallFromMutationObserver(flush);

// MessageChannels are desirable because they give direct access to the HTML
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
// 11-12, and in web workers in many engines.
// Although message channels yield to any queued rendering and IO tasks, they
// would be better than imposing the 4ms delay of timers.
// However, they do not work reliably in Internet Explorer or Safari.

// Internet Explorer 10 is the only browser that has setImmediate but does
// not have MutationObservers.
// Although setImmediate yields to the browser's renderer, it would be
// preferrable to falling back to setTimeout since it does not have
// the minimum 4ms penalty.
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
// Desktop to a lesser extent) that renders both setImmediate and
// MessageChannel useless for the purposes of ASAP.
// https://github.com/kriskowal/q/issues/396

// Timers are implemented universally.
// We fall back to timers in workers in most engines, and in foreground
// contexts in the following browsers.
// However, note that even this simple case requires nuances to operate in a
// broad spectrum of browsers.
//
// - Firefox 3-13
// - Internet Explorer 6-9
// - iPad Safari 4.3
// - Lynx 2.8.7
} else {
    requestFlush = makeRequestCallFromTimer(flush);
}

// `requestFlush` requests that the high priority event queue be flushed as
// soon as possible.
// This is useful to prevent an error thrown in a task from stalling the event
// queue if the exception handled by Node.js’s
// `process.on("uncaughtException")` or by a domain.
rawAsap.requestFlush = requestFlush;

// To request a high priority event, we induce a mutation observer by toggling
// the text of a text node between "1" and "-1".
function makeRequestCallFromMutationObserver(callback) {
    var toggle = 1;
    var observer = new BrowserMutationObserver(callback);
    var node = document.createTextNode("");
    observer.observe(node, {characterData: true});
    return function requestCall() {
        toggle = -toggle;
        node.data = toggle;
    };
}

// The message channel technique was discovered by Malte Ubl and was the
// original foundation for this library.
// http://www.nonblocking.io/2011/06/windownexttick.html

// Safari 6.0.5 (at least) intermittently fails to create message ports on a
// page's first load. Thankfully, this version of Safari supports
// MutationObservers, so we don't need to fall back in that case.

// function makeRequestCallFromMessageChannel(callback) {
//     var channel = new MessageChannel();
//     channel.port1.onmessage = callback;
//     return function requestCall() {
//         channel.port2.postMessage(0);
//     };
// }

// For reasons explained above, we are also unable to use `setImmediate`
// under any circumstances.
// Even if we were, there is another bug in Internet Explorer 10.
// It is not sufficient to assign `setImmediate` to `requestFlush` because
// `setImmediate` must be called *by name* and therefore must be wrapped in a
// closure.
// Never forget.

// function makeRequestCallFromSetImmediate(callback) {
//     return function requestCall() {
//         setImmediate(callback);
//     };
// }

// Safari 6.0 has a problem where timers will get lost while the user is
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
// mutation observers, so that implementation is used instead.
// However, if we ever elect to use timers in Safari, the prevalent work-around
// is to add a scroll event listener that calls for a flush.

// `setTimeout` does not call the passed callback if the delay is less than
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
// even then.

function makeRequestCallFromTimer(callback) {
    return function requestCall() {
        // We dispatch a timeout with a specified delay of 0 for engines that
        // can reliably accommodate that request. This will usually be snapped
        // to a 4 milisecond delay, but once we're flushing, there's no delay
        // between events.
        var timeoutHandle = setTimeout(handleTimer, 0);
        // However, since this timer gets frequently dropped in Firefox
        // workers, we enlist an interval handle that will try to fire
        // an event 20 times per second until it succeeds.
        var intervalHandle = setInterval(handleTimer, 50);

        function handleTimer() {
            // Whichever timer succeeds will cancel both timers and
            // execute the callback.
            clearTimeout(timeoutHandle);
            clearInterval(intervalHandle);
            callback();
        }
    };
}

// This is for `asap.js` only.
// Its name will be periodically randomized to break any code that depends on
// its existence.
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;

// ASAP was originally a nextTick shim included in Q. This was factored out
// into this ASAP package. It was later adapted to RSVP which made further
// amendments. These decisions, particularly to marginalize MessageChannel and
// to capture the MutationObserver implementation in a closure, were integrated
// back into ASAP proper.
// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
<commit_msg>Fixed check for MutationObserver in environments with different global objects. (#68)<commit_after>"use strict";

// Use the fastest means possible to execute a task in its own turn, with
// priority over other events including IO, animation, reflow, and redraw
// events in browsers.
//
// An exception thrown by a task will permanently interrupt the processing of
// subsequent tasks. The higher level `asap` function ensures that if an
// exception is thrown by a task, that the task queue will continue flushing as
// soon as possible, but if you use `rawAsap` directly, you are responsible to
// either ensure that no exceptions are thrown from your task, or to manually
// call `rawAsap.requestFlush` if an exception is thrown.
module.exports = rawAsap;
function rawAsap(task) {
    if (!queue.length) {
        requestFlush();
        flushing = true;
    }
    // Equivalent to push, but avoids a function call.
    queue[queue.length] = task;
}

var queue = [];
// Once a flush has been requested, no further calls to `requestFlush` are
// necessary until the next `flush` completes.
var flushing = false;
// `requestFlush` is an implementation-specific method that attempts to kick
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
// the event queue before yielding to the browser's own event loop.
var requestFlush;
// The position of the next task to execute in the task queue. This is
// preserved between calls to `flush` so that it can be resumed if
// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grow
// unbounded. To prevent memory exhaustion, the task queue will periodically
// truncate already-completed tasks.
var capacity = 1024;

// The flush function processes all tasks that have been scheduled with
// `rawAsap` unless and until one of those tasks throws an exception.
// If a task throws an exception, `flush` ensures that its state will remain
// consistent and will resume where it left off when called again.
// However, `flush` does not make any arrangements to be called again if an
// exception is thrown.
function flush() {
    while (index < queue.length) {
        var currentIndex = index;
        // Advance the index before calling the task. This ensures that we will
        // begin flushing on the next task the task throws an error.
        index = index + 1;
        queue[currentIndex].call();
        // Prevent leaking memory for long chains of recursive calls to `asap`.
        // If we call `asap` within tasks scheduled by `asap`, the queue will
        // grow, but to avoid an O(n) walk for every task we execute, we don't
        // shift tasks off the queue after they have been executed.
        // Instead, we periodically shift 1024 tasks off the queue.
        if (index > capacity) {
            // Manually shift all values starting at the index back to the
            // beginning of the queue.
            for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
                queue[scan] = queue[scan + index];
            }
            queue.length -= index;
            index = 0;
        }
    }
    queue.length = 0;
    index = 0;
    flushing = false;
}

// `requestFlush` is implemented using a strategy based on data collected from
// every available SauceLabs Selenium web driver worker at time of writing.
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593

// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
// have WebKitMutationObserver but not un-prefixed MutationObserver.
// Must use `global` or `self` instead of `window` to work in both frames and web
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.

/* globals self */
var scope = typeof global !== "undefined" ? global : self;
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;

// MutationObservers are desirable because they have high priority and work
// reliably everywhere they are implemented.
// They are implemented in all modern browsers.
//
// - Android 4-4.3
// - Chrome 26-34
// - Firefox 14-29
// - Internet Explorer 11
// - iPad Safari 6-7.1
// - iPhone Safari 7-7.1
// - Safari 6-7
if (typeof BrowserMutationObserver === "function") {
    requestFlush = makeRequestCallFromMutationObserver(flush);

// MessageChannels are desirable because they give direct access to the HTML
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
// 11-12, and in web workers in many engines.
// Although message channels yield to any queued rendering and IO tasks, they
// would be better than imposing the 4ms delay of timers.
// However, they do not work reliably in Internet Explorer or Safari.

// Internet Explorer 10 is the only browser that has setImmediate but does
// not have MutationObservers.
// Although setImmediate yields to the browser's renderer, it would be
// preferrable to falling back to setTimeout since it does not have
// the minimum 4ms penalty.
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
// Desktop to a lesser extent) that renders both setImmediate and
// MessageChannel useless for the purposes of ASAP.
// https://github.com/kriskowal/q/issues/396

// Timers are implemented universally.
// We fall back to timers in workers in most engines, and in foreground
// contexts in the following browsers.
// However, note that even this simple case requires nuances to operate in a
// broad spectrum of browsers.
//
// - Firefox 3-13
// - Internet Explorer 6-9
// - iPad Safari 4.3
// - Lynx 2.8.7
} else {
    requestFlush = makeRequestCallFromTimer(flush);
}

// `requestFlush` requests that the high priority event queue be flushed as
// soon as possible.
// This is useful to prevent an error thrown in a task from stalling the event
// queue if the exception handled by Node.js’s
// `process.on("uncaughtException")` or by a domain.
rawAsap.requestFlush = requestFlush;

// To request a high priority event, we induce a mutation observer by toggling
// the text of a text node between "1" and "-1".
function makeRequestCallFromMutationObserver(callback) {
    var toggle = 1;
    var observer = new BrowserMutationObserver(callback);
    var node = document.createTextNode("");
    observer.observe(node, {characterData: true});
    return function requestCall() {
        toggle = -toggle;
        node.data = toggle;
    };
}

// The message channel technique was discovered by Malte Ubl and was the
// original foundation for this library.
// http://www.nonblocking.io/2011/06/windownexttick.html

// Safari 6.0.5 (at least) intermittently fails to create message ports on a
// page's first load. Thankfully, this version of Safari supports
// MutationObservers, so we don't need to fall back in that case.

// function makeRequestCallFromMessageChannel(callback) {
//     var channel = new MessageChannel();
//     channel.port1.onmessage = callback;
//     return function requestCall() {
//         channel.port2.postMessage(0);
//     };
// }

// For reasons explained above, we are also unable to use `setImmediate`
// under any circumstances.
// Even if we were, there is another bug in Internet Explorer 10.
// It is not sufficient to assign `setImmediate` to `requestFlush` because
// `setImmediate` must be called *by name* and therefore must be wrapped in a
// closure.
// Never forget.

// function makeRequestCallFromSetImmediate(callback) {
//     return function requestCall() {
//         setImmediate(callback);
//     };
// }

// Safari 6.0 has a problem where timers will get lost while the user is
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
// mutation observers, so that implementation is used instead.
// However, if we ever elect to use timers in Safari, the prevalent work-around
// is to add a scroll event listener that calls for a flush.

// `setTimeout` does not call the passed callback if the delay is less than
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
// even then.

function makeRequestCallFromTimer(callback) {
    return function requestCall() {
        // We dispatch a timeout with a specified delay of 0 for engines that
        // can reliably accommodate that request. This will usually be snapped
        // to a 4 milisecond delay, but once we're flushing, there's no delay
        // between events.
        var timeoutHandle = setTimeout(handleTimer, 0);
        // However, since this timer gets frequently dropped in Firefox
        // workers, we enlist an interval handle that will try to fire
        // an event 20 times per second until it succeeds.
        var intervalHandle = setInterval(handleTimer, 50);

        function handleTimer() {
            // Whichever timer succeeds will cancel both timers and
            // execute the callback.
            clearTimeout(timeoutHandle);
            clearInterval(intervalHandle);
            callback();
        }
    };
}

// This is for `asap.js` only.
// Its name will be periodically randomized to break any code that depends on
// its existence.
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;

// ASAP was originally a nextTick shim included in Q. This was factored out
// into this ASAP package. It was later adapted to RSVP which made further
// amendments. These decisions, particularly to marginalize MessageChannel and
// to capture the MutationObserver implementation in a closure, were integrated
// back into ASAP proper.
// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
<|endoftext|>


<commit_before>/* @flow */
import * as path from 'path'
import { childProcess, fs } from 'node-promise-es6'

export async function exec (
  command: string,
  {
    cwd = path.resolve(),
    env = process.env
  }: {
    cwd?: string,
    env?: { [string]: ?string }
  } = {}
): Promise<string> {
  console.log(env)
  const { stdout } = await childProcess.exec(command, { cwd, env })
  return stdout.trim()
}

export async function readFile (filePath: string): Promise<string> {
  const contents = await fs.readFile(filePath, 'utf8')
  return contents.trim()
}

export async function removeDirectory (name: string): Promise<void> {
  await exec(`rm -rf '${name}'`)
}
<commit_msg>Log env only for failing test<commit_after>/* @flow */
import * as path from 'path'
import { childProcess, fs } from 'node-promise-es6'

export async function exec (
  command: string,
  {
    cwd = path.resolve(),
    env = process.env
  }: {
    cwd?: string,
    env?: { [string]: ?string }
  } = {}
): Promise<string> {
  if (command.startsWith('hub clone')) {
    console.log(env.GITHUB_TOKEN)
  }
  const { stdout } = await childProcess.exec(command, { cwd, env })
  return stdout.trim()
}

export async function readFile (filePath: string): Promise<string> {
  const contents = await fs.readFile(filePath, 'utf8')
  return contents.trim()
}

export async function removeDirectory (name: string): Promise<void> {
  await exec(`rm -rf '${name}'`)
}
<|endoftext|>


<commit_before><commit_msg>BUILD<commit_after><|endoftext|>


<commit_before>const CACHE_NAME = `typewritesomething@${process.env.npm_package_version}-${process.env.git_hash}`;

// the rest below handles the installing and caching
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then((cache) => {
        // problematic files for firefox
        cache.addAll([
          '/static/audio/keypress.mp3',
          '/static/audio/return.mp3',
        ]);

        return cache.addAll([
          '/',
          '/dist/main.js',
          '/favicon.ico',
          '/index.html',
          '/manifest.json',
          '/static/style.css',
          '/static/fonts/specialelite-webfont.ttf',
          '/static/fonts/specialelite-webfont.woff',
          '/static/fonts/specialelite-webfont.woff2',
          '/static/img/handmadepaper.png',
          '/static/img/logo-on-bg-36.png',
          '/static/img/logo-on-bg-96.png',
          '/static/img/logo-on-bg-144.png',
          '/static/img/logo-on-bg-512.png',
          '/static/img/logo-on-bg.png',
        ]);
      })
      .then(self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches
      .keys()
      .then((cacheNames) => {
        return cacheNames.filter((cacheName) => cacheName !== CACHE_NAME);
      })
      .then((cachesToDelete) => {
        return Promise.all(
          cachesToDelete.map((cacheToDelete) => {
            return caches.delete(cacheToDelete);
          })
        );
      })
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then((cachedResponse) => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return fetch(event.request).then((response) => {
          caches.open(CACHE_NAME).then((cache) => {
            cache.put(event.request, response);
          });

          return response.clone();
        });
      })
    );
  }
});
<commit_msg>force update<commit_after>const CACHE_NAME = `typewritesomething@${process.env.npm_package_version}-${process.env.git_hash}`;

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then((cache) => {
        // problematic files for firefox
        cache.addAll([
          '/static/audio/keypress.mp3',
          '/static/audio/return.mp3',
        ]);

        return cache.addAll([
          '/',
          '/dist/main.js',
          '/favicon.ico',
          '/index.html',
          '/manifest.json',
          '/static/style.css',
          '/static/fonts/specialelite-webfont.ttf',
          '/static/fonts/specialelite-webfont.woff',
          '/static/fonts/specialelite-webfont.woff2',
          '/static/img/handmadepaper.png',
          '/static/img/logo-on-bg-36.png',
          '/static/img/logo-on-bg-96.png',
          '/static/img/logo-on-bg-144.png',
          '/static/img/logo-on-bg-512.png',
          '/static/img/logo-on-bg.png',
        ]);
      })
      .then(self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches
      .keys()
      .then((cacheNames) => {
        return cacheNames.filter((cacheName) => cacheName !== CACHE_NAME);
      })
      .then((cachesToDelete) => {
        return Promise.all(
          cachesToDelete.map((cacheToDelete) => {
            return caches.delete(cacheToDelete);
          })
        );
      })
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then((cachedResponse) => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return fetch(event.request).then((response) => {
          caches.open(CACHE_NAME).then((cache) => {
            cache.put(event.request, response);
          });

          return response.clone();
        });
      })
    );
  }
});
<|endoftext|>


<commit_before>const CACHE_NAME = `typewritesomething@${process.env.npm_package_version}-${process.env.git_hash}`;

// list the files you want cached by the service worker
PRECACHE_URLS = ['/index.html', '/dist/main.js'];

// the rest below handles the installing and caching
self.addEventListener('install', (event) => {
  console.log('install');
  event.waitUntil(
    caches
      .open(PRECACHE)
      .then((cache) => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  console.log('activate');
  const currentCaches = [PRECACHE, RUNTIME];
  event.waitUntil(
    caches
      .keys()
      .then((cacheNames) => {
        return cacheNames.filter(
          (cacheName) => !currentCaches.includes(cacheName)
        );
      })
      .then((cachesToDelete) => {
        return Promise.all(
          cachesToDelete.map((cacheToDelete) => {
            return caches.delete(cacheToDelete);
          })
        );
      })
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then((cachedResponse) => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return caches.open(RUNTIME).then((cache) => {
          return fetch(event.request).then((response) => {
            return response;
          });
        });
      })
    );
  }
});
<commit_msg>fix to missing variable names<commit_after>const CACHE_NAME = `typewritesomething@${process.env.npm_package_version}-${process.env.git_hash}`;

// list the files you want cached by the service worker
PRECACHE_URLS = ['/index.html', '/dist/main.js'];

// the rest below handles the installing and caching
self.addEventListener('install', (event) => {
  console.log('install');
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then((cache) => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  console.log('activate');
  const currentCaches = [CACHE_NAME];
  event.waitUntil(
    caches
      .keys()
      .then((cacheNames) => {
        return cacheNames.filter(
          (cacheName) => !currentCaches.includes(cacheName)
        );
      })
      .then((cachesToDelete) => {
        return Promise.all(
          cachesToDelete.map((cacheToDelete) => {
            return caches.delete(cacheToDelete);
          })
        );
      })
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then((cachedResponse) => {
        if (cachedResponse) {
          return cachedResponse;
        }

        console.log('fetching', event.request);

        return caches.open(CACHE_NAME).then((cache) => {
          return fetch(event.request).then((response) => {
            return response;
          });
        });
      })
    );
  }
});
<|endoftext|>


<commit_before>var inputProcessingYielder = new Yielder;

function initialInputChanged() {
    cancelInputProcessing();
    resetEntities();
    $("#inputWindow").addClass("disabled");
    $("#inputWindow button").attr("disabled","disabled");
}
function initialInputUpdated() {
    $(".inputLoading").show()

    if ($("#initialInput")[0].value === "") {
        $(".inputLoading").hide();
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
        $("#inputWindow .screen").hide();
    }
    handleInput(function() {
        $(".inputLoading").hide()
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
    });
}
function inputError(text) {
    addInputWarning(text);
    $(".inputLoading").hide();
    $("#inputWindow").removeClass("disabled");
    $("#inputWindow button").removeAttr("disabled");
    $("#inputWindow .screen").hide();
}
function cancelInputProcessing() {
    $(".inputLoading").hide()
    inputProcessingYielder.cancel();
}

function handleInput(callback) {
    inputProcessingYielder = new Yielder();
    var input = $('#initialInput')[0].value;
    function onProgressMade() {
        $(".inputLoading").hide();
        $("#inputWindow .screen").hide();
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
    }
    function onAmbiguity(ambiguousRecord, onAmbiguityResolved) {
        onProgressMade();
        showAmbiguousRowPrompt(ambiguousRecord, onAmbiguityResolved);
    }
    function onComplete() {
        showConfirmationSpreadsheet(onProgressMade);
    }
    parseInput(input, onAmbiguity, onComplete, inputProcessingYielder);
}

function showAmbiguousRowPrompt(ambiguousRecord, onAmbiguityResolved) {
    //an ugly hack, should rework groupProperties and friends to understand headerPaths
    var headers = $.map(headerPaths, function(headerPath) {return headerPath.toComplexProp()});
    var groupedHeaders = groupProperties(headers);
    var context = $("#formatDisambiguation");
    $("table thead",context).replaceWith(buildTableHeaders(groupedHeaders));

    var headerProps = groupedHeaders.getPropsForRows();
    var rowHTML = function(row){
        var html = "
";
        for (var i = 0; i < headerProps.length; i++) {
            html += ""
            var val = row[$.inArray(headerProps[i],headers)] || "";
            if (typeof val == "string")
                html += val;
            else
                for (var j = 0; j < val.length; j++)
                    if (val[j] != undefined)
                        html += val[j] + "
";
            html += "<\/td>";
        }
        return html + "<\/tr>";
    }

    var separateRows = $.map(ambiguousRecord, rowHTML).join("");
    var numThings = ambiguousRecord.length;

    $("table tbody", context).html(separateRows);

    var tree = mapTreeToEntity(recordToTree(ambiguousRecord));
    $(".thingName", context).html(textValue(tree));
    var thingType = tree['/type/object/type'];
    if (thingType){
        var thingTypeEl = $(".thingType", context);
        freebase.getName(thingType[0],function(name){
            thingTypeEl.html(name);
        });
    }
    $(".numThings", context).html(numThings);

    function ambiguityWrapper(shouldCombine) {
        $("button", context).attr("disabled","disabled");
        onAmbiguityResolved(shouldCombine);
    }
    $(".doCombine", context).unbind("click").click(function() {ambiguityWrapper(true);});
    $(".dontCombine", context).unbind("click").click(function() {ambiguityWrapper(false);});

    $('table tbody tr:odd', context).addClass('odd');
    $('table tbody tr:even', context).addClass('even');
    context.show();
}
function showConfirmationSpreadsheet(beforeDisplay) {
    var spreadSheetData = {"aoColumns":[], "aaData":[]};
    var columnNames = $.map(headerPaths, function(header) {return header.getDisplayName();});
    for (var i = 0; i < columnNames.length; i++)
        spreadSheetData.aoColumns.push({"sTitle":columnNames[i]});
    politeEach(rows, function(_,entity) {
        var row = [];
        for (var j = 0; j < headerPaths.length; j++){
            var val = entity.get(headerPaths[j]);
            if (val == undefined)
                val = "";
            else if ($.isArray(val)){
                var arr = Arr.filter(val, function(elem) {return elem !== undefined;});
                if (arr.length === 0)
                    val = "";
                else if (arr.length === 1)
                    val = "" + textValue(arr[0]);
                else
                    val = textValue(val);
            }

            row[j] = val;
        }
        spreadSheetData.aaData.push(row);
    }, function() {
        if (beforeDisplay) beforeDisplay();
        updateUnreconciledCount();
        spreadSheetData["bAutoWidth"] = false;
        spreadSheetData["bSort"] = false;
        $("#spreadsheetDiv").html('
<\/table>');
        $('#spreadsheetTable').dataTable(spreadSheetData);
        $('#spreadsheetPreview').show();
    });

}
var previousSelectedTab = 0;
function initializeTabs() {
    var tabs = $("#tabs > ul");
    tabs.tabs();
    tabs.bind("tabsselect", function(event, ui) {
        switch(previousSelectedTab){
          case 1: onHideRenderScreen(); break;
          case 2: onHideOutputScreen(); break;
        }
        switch(ui.index){
          case 0: manualReconcile(); break;
          case 1: onDisplayRenderScreen(); break;
          case 2: onDisplayOutputScreen(); break;
        }
        previousSelectedTab = ui.index;
    });
    $("#tabs").show();
    tabs.tabs("select", 0);
}
function continueToReconciliation() {
    $("#gettingInput").remove();
    initializeTabs();
    addIdColumns();
    initializeReconciliation(beginAutoReconciliation);
}
var reconciliationBegun = false;
var defaultMDOName = "Spreadsheet Upload about (kind of data)"
$(document).ready(function() {
    jQuery.ajaxSettings.cache = true; //keeps jquery from inserting cache-busting timecodes into json requests

    $("#progressbar").progressbar({value:0});
    window.onbeforeunload = function() {
        if (reconciliationBegun)
            return "You may have unsaved changes.  Make sure to copy your updated spreadsheet or upload your data to Freebase on the Retrieve Your Data tab.";
    };

	if ("LOADER_VERSION" in window) {
	    var version = window['LOADER_VERSION'];
	    $(".versionLink").attr("href","http://github.com/freebase/reconciliation_ui/commit/" + version);
	    var bugReportDetails = "&description=" + escape("Found in version: " + version + "\r\n\r\n");
	    $(".bugReportLink").attr("href", $(".bugReportLink").attr("href") + bugReportDetails);
	    freebase.beacon("ready");
	}

    var capture_tab = function(event) {
        if (event.keyCode == 9) {
            if (event.type === "keydown")
                $("#initialInput").insertAtCaret("\t");
            event.returnValue = false;
            return false;
        }
        return true;
    }
    $("#initialInput").keypress(capture_tab).keydown(capture_tab);

    var inputThrottler = throttler(initialInputChanged, initialInputUpdated);
    var harmlessKeys = new Set(37,38,39,40,91,93,20,35,36,33,34,27,18,17,16,224);
    var inputFilterer = function(event) {
        if (harmlessKeys.contains(event.keyCode))
            return;
        //ctrl-a or cmd-a
        if ((event.metaKey || event.ctrlKey) && event.keyCode === 65)
            return;
        inputThrottler();
    }

    $("#initialInput").keyup(inputFilterer).keydown(inputFilterer);
	$("#initialInput").bind("paste", null, inputThrottler);
	//for IE
	$("#initialInput")[0].onpaste = inputThrottler;
    //for most everyone else's browsers
	$("#initialInput")[0].oninput = inputThrottler;
    if ($("#initialInput")[0].value != "") inputThrottler();

    $("#spreadsheetPreview button.continue").click(continueToReconciliation);
});

function updateUnreconciledCount() {
    var pctProgress = (((totalRecords - automaticQueue.length) / totalRecords) * 100);
    $("#progressbar").progressbar("value", pctProgress);
    $("#progressbar label").html(pctProgress.toFixed(1) + "%");
    $(".manual_count").html("("+numProperties(manualQueue)+")");
}

function updateMdoInfo() {
    var mdo_info = {software_tool:"/guid/9202a8c04000641f800000000df257ed"};
    var name = $("#mdo_name")[0].value;
    if (name != "" && name != defaultMDOName)
       mdo_info.name = name;
    var info_source = $("#mdo_data_source_id")[0].value;
    if (info_source != "")
       mdo_info.info_source = info_source;
    $("#mdo_info")[0].value = JSON.stringify(mdo_info);
}

var freebase_url = "http://www.freebase.com/";
var reconciliation_url = "http://data.labs.freebase.com/recon/";

/* Takes a string and populates the initialInput textarea. */
function handlePOSTdata(data) {
    $('#initialInput')[0].value = data;
    initialInputUpdated();
}

var inputWarnings = {};
function addInputWarning(text) {
    if (text in inputWarnings)
        return;
    else
        inputWarnings[text] = true;
    $(".inputWarnings").show()
    $(".inputWarnings ul").append(node("li", text));
}

function clearInputWarnings() {
    inputWarnings = {};
    $(".inputWarnings").hide()
    $(".inputWarnings ul").empty();
}<commit_msg>Don't show more than five warnings at once<commit_after>var inputProcessingYielder = new Yielder;

function initialInputChanged() {
    cancelInputProcessing();
    resetEntities();
    $("#inputWindow").addClass("disabled");
    $("#inputWindow button").attr("disabled","disabled");
}
function initialInputUpdated() {
    $(".inputLoading").show()

    if ($("#initialInput")[0].value === "") {
        $(".inputLoading").hide();
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
        $("#inputWindow .screen").hide();
    }
    handleInput(function() {
        $(".inputLoading").hide()
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
    });
}
function inputError(text) {
    addInputWarning(text);
    $(".inputLoading").hide();
    $("#inputWindow").removeClass("disabled");
    $("#inputWindow button").removeAttr("disabled");
    $("#inputWindow .screen").hide();
}
function cancelInputProcessing() {
    $(".inputLoading").hide()
    inputProcessingYielder.cancel();
}

function handleInput(callback) {
    inputProcessingYielder = new Yielder();
    var input = $('#initialInput')[0].value;
    function onProgressMade() {
        $(".inputLoading").hide();
        $("#inputWindow .screen").hide();
        $("#inputWindow").removeClass("disabled");
        $("#inputWindow button").removeAttr("disabled");
    }
    function onAmbiguity(ambiguousRecord, onAmbiguityResolved) {
        onProgressMade();
        showAmbiguousRowPrompt(ambiguousRecord, onAmbiguityResolved);
    }
    function onComplete() {
        showConfirmationSpreadsheet(onProgressMade);
    }
    parseInput(input, onAmbiguity, onComplete, inputProcessingYielder);
}

function showAmbiguousRowPrompt(ambiguousRecord, onAmbiguityResolved) {
    //an ugly hack, should rework groupProperties and friends to understand headerPaths
    var headers = $.map(headerPaths, function(headerPath) {return headerPath.toComplexProp()});
    var groupedHeaders = groupProperties(headers);
    var context = $("#formatDisambiguation");
    $("table thead",context).replaceWith(buildTableHeaders(groupedHeaders));

    var headerProps = groupedHeaders.getPropsForRows();
    var rowHTML = function(row){
        var html = "
";
        for (var i = 0; i < headerProps.length; i++) {
            html += ""
            var val = row[$.inArray(headerProps[i],headers)] || "";
            if (typeof val == "string")
                html += val;
            else
                for (var j = 0; j < val.length; j++)
                    if (val[j] != undefined)
                        html += val[j] + "
";
            html += "<\/td>";
        }
        return html + "<\/tr>";
    }

    var separateRows = $.map(ambiguousRecord, rowHTML).join("");
    var numThings = ambiguousRecord.length;

    $("table tbody", context).html(separateRows);

    var tree = mapTreeToEntity(recordToTree(ambiguousRecord));
    $(".thingName", context).html(textValue(tree));
    var thingType = tree['/type/object/type'];
    if (thingType){
        var thingTypeEl = $(".thingType", context);
        freebase.getName(thingType[0],function(name){
            thingTypeEl.html(name);
        });
    }
    $(".numThings", context).html(numThings);

    function ambiguityWrapper(shouldCombine) {
        $("button", context).attr("disabled","disabled");
        onAmbiguityResolved(shouldCombine);
    }
    $(".doCombine", context).unbind("click").click(function() {ambiguityWrapper(true);});
    $(".dontCombine", context).unbind("click").click(function() {ambiguityWrapper(false);});

    $('table tbody tr:odd', context).addClass('odd');
    $('table tbody tr:even', context).addClass('even');
    context.show();
}
function showConfirmationSpreadsheet(beforeDisplay) {
    var spreadSheetData = {"aoColumns":[], "aaData":[]};
    var columnNames = $.map(headerPaths, function(header) {return header.getDisplayName();});
    for (var i = 0; i < columnNames.length; i++)
        spreadSheetData.aoColumns.push({"sTitle":columnNames[i]});
    politeEach(rows, function(_,entity) {
        var row = [];
        for (var j = 0; j < headerPaths.length; j++){
            var val = entity.get(headerPaths[j]);
            if (val == undefined)
                val = "";
            else if ($.isArray(val)){
                var arr = Arr.filter(val, function(elem) {return elem !== undefined;});
                if (arr.length === 0)
                    val = "";
                else if (arr.length === 1)
                    val = "" + textValue(arr[0]);
                else
                    val = textValue(val);
            }

            row[j] = val;
        }
        spreadSheetData.aaData.push(row);
    }, function() {
        if (beforeDisplay) beforeDisplay();
        updateUnreconciledCount();
        spreadSheetData["bAutoWidth"] = false;
        spreadSheetData["bSort"] = false;
        $("#spreadsheetDiv").html('
<\/table>');
        $('#spreadsheetTable').dataTable(spreadSheetData);
        $('#spreadsheetPreview').show();
    });

}
var previousSelectedTab = 0;
function initializeTabs() {
    var tabs = $("#tabs > ul");
    tabs.tabs();
    tabs.bind("tabsselect", function(event, ui) {
        switch(previousSelectedTab){
          case 1: onHideRenderScreen(); break;
          case 2: onHideOutputScreen(); break;
        }
        switch(ui.index){
          case 0: manualReconcile(); break;
          case 1: onDisplayRenderScreen(); break;
          case 2: onDisplayOutputScreen(); break;
        }
        previousSelectedTab = ui.index;
    });
    $("#tabs").show();
    tabs.tabs("select", 0);
}
function continueToReconciliation() {
    $("#gettingInput").remove();
    initializeTabs();
    addIdColumns();
    initializeReconciliation(beginAutoReconciliation);
}
var reconciliationBegun = false;
var defaultMDOName = "Spreadsheet Upload about (kind of data)"
$(document).ready(function() {
    jQuery.ajaxSettings.cache = true; //keeps jquery from inserting cache-busting timecodes into json requests

    $("#progressbar").progressbar({value:0});
    window.onbeforeunload = function() {
        if (reconciliationBegun)
            return "You may have unsaved changes.  Make sure to copy your updated spreadsheet or upload your data to Freebase on the Retrieve Your Data tab.";
    };

	if ("LOADER_VERSION" in window) {
	    var version = window['LOADER_VERSION'];
	    $(".versionLink").attr("href","http://github.com/freebase/reconciliation_ui/commit/" + version);
	    var bugReportDetails = "&description=" + escape("Found in version: " + version + "\r\n\r\n");
	    $(".bugReportLink").attr("href", $(".bugReportLink").attr("href") + bugReportDetails);
	    freebase.beacon("ready");
	}

    var capture_tab = function(event) {
        if (event.keyCode == 9) {
            if (event.type === "keydown")
                $("#initialInput").insertAtCaret("\t");
            event.returnValue = false;
            return false;
        }
        return true;
    }
    $("#initialInput").keypress(capture_tab).keydown(capture_tab);

    var inputThrottler = throttler(initialInputChanged, initialInputUpdated);
    var harmlessKeys = new Set(37,38,39,40,91,93,20,35,36,33,34,27,18,17,16,224);
    var inputFilterer = function(event) {
        if (harmlessKeys.contains(event.keyCode))
            return;
        //ctrl-a or cmd-a
        if ((event.metaKey || event.ctrlKey) && event.keyCode === 65)
            return;
        inputThrottler();
    }

    $("#initialInput").keyup(inputFilterer).keydown(inputFilterer);
	$("#initialInput").bind("paste", null, inputThrottler);
	//for IE
	$("#initialInput")[0].onpaste = inputThrottler;
    //for most everyone else's browsers
	$("#initialInput")[0].oninput = inputThrottler;
    if ($("#initialInput")[0].value != "") inputThrottler();

    $("#spreadsheetPreview button.continue").click(continueToReconciliation);
});

function updateUnreconciledCount() {
    var pctProgress = (((totalRecords - automaticQueue.length) / totalRecords) * 100);
    $("#progressbar").progressbar("value", pctProgress);
    $("#progressbar label").html(pctProgress.toFixed(1) + "%");
    $(".manual_count").html("("+numProperties(manualQueue)+")");
}

function updateMdoInfo() {
    var mdo_info = {software_tool:"/guid/9202a8c04000641f800000000df257ed"};
    var name = $("#mdo_name")[0].value;
    if (name != "" && name != defaultMDOName)
       mdo_info.name = name;
    var info_source = $("#mdo_data_source_id")[0].value;
    if (info_source != "")
       mdo_info.info_source = info_source;
    $("#mdo_info")[0].value = JSON.stringify(mdo_info);
}

var freebase_url = "http://www.freebase.com/";
var reconciliation_url = "http://data.labs.freebase.com/recon/";

/* Takes a string and populates the initialInput textarea. */
function handlePOSTdata(data) {
    $('#initialInput')[0].value = data;
    initialInputUpdated();
}

var inputWarnings = {};
function addInputWarning(text) {
    if (numProperties(inputWarnings) >= 4)
        displayInputWarning("Additional warnings hidden");
    else
        displayInputWarning(text);

    function displayInputWarning(text) {
        if (text in inputWarnings)
            return;
        else
            inputWarnings[text] = true;

        $(".inputWarnings").show()
        $(".inputWarnings ul").append(node("li", text));
    }
}

function clearInputWarnings() {
    inputWarnings = {};
    $(".inputWarnings").hide()
    $(".inputWarnings ul").empty();
}<|endoftext|>


<commit_before>function Ui(ui_container) {
    this.container(ui_container);
    this.board(null);
    this.displayed_board(null);
    this.row(0);
    this.column(0);
    this.displayed_row(null);
}

accessor(Ui, "container");
accessor(Ui, "board");
accessor(Ui, "displayed_board");
accessor(Ui, "row");
accessor(Ui, "column");
accessor(Ui, "displayed_row");

Ui.prototype.cell_class= function() {
    return this.board().cell_color(this.row(), this.column()) + "-cell";
}

Ui.prototype.cell_contents= function() {
    if (this.board().is_ant_at(this.row(), this.column()))
	return "";
    return "";
};

Ui.prototype.start_row= function() {
    this.displayed_row($("

").appendTo(this.displayed_board()));
};

Ui.prototype.done= function() {
    return this.row() >= this.board().height();
};

Ui.prototype.display= function(a_board) {
    this.board(a_board);
    this.displayed_board($("

").appendTo(this.container()));
    while (!this.done()) {
	if (this.column() === 0)
	    this.start_row();

	$("" + this.cell_contents() + "	").appendTo(this.displayed_row());
	this.column(this.column() + 1);

	if (this.column() >= this.board().width()) {
	    this.column(0);
	    this.row(this.row() + 1);
	}
    }
};
<commit_msg>Refactoring: extracted Ui.next_cell()<commit_after>function Ui(ui_container) {
    this.container(ui_container);
    this.board(null);
    this.displayed_board(null);
    this.row(0);
    this.column(0);
    this.displayed_row(null);
}

accessor(Ui, "container");
accessor(Ui, "board");
accessor(Ui, "displayed_board");
accessor(Ui, "row");
accessor(Ui, "column");
accessor(Ui, "displayed_row");

Ui.prototype.cell_class= function() {
    return this.board().cell_color(this.row(), this.column()) + "-cell";
}

Ui.prototype.cell_contents= function() {
    if (this.board().is_ant_at(this.row(), this.column()))
	return "";
    return "";
};

Ui.prototype.start_row= function() {
    this.displayed_row($("

").appendTo(this.displayed_board()));
};

Ui.prototype.done= function() {
    return this.row() >= this.board().height();
};

Ui.prototype.next_cell= function() {
    this.column(this.column() + 1);
    if (this.column() >= this.board().width()) {
	this.column(0);
	this.row(this.row() + 1);
    }
};

Ui.prototype.display= function(a_board) {
    this.board(a_board);
    this.displayed_board($("

").appendTo(this.container()));
    while (!this.done()) {
	if (this.column() === 0)
	    this.start_row();

	$("" + this.cell_contents() + "	").appendTo(this.displayed_row());
	this.next_cell();
    }
};
<|endoftext|>