<commit_before>import Router from 'vue-router'
import Board from '../components/Board.vue'
import Sidebar from '../components/Sidebar.vue'
import Thread from '../components/Thread.vue'

Vue.use(Router)

const routes = [
    {
        path: '/',
        components: {
            main: Board,
            sidebar: Sidebar
        }
    },
    {
        path: '/thread/:id/:slug/',
        components: {
            main: Thread,
            sidebar: Sidebar
        }
    }
]

const router = new Router({
    routes,
    scrollBehavior (to, from, savedPosition) {
        return savedPosition ? savedPosition : { x: 0, y: 0}
    }
})

export default router<commit_msg>change router to history mode.<commit_after>import Router from 'vue-router'
import Board from '../components/Board.vue'
import Sidebar from '../components/Sidebar.vue'
import Thread from '../components/Thread.vue'

Vue.use(Router)

const routes = [
    {
        path: '/',
        components: {
            main: Board,
            sidebar: Sidebar
        }
    },
    {
        path: '/thread/:id/:slug/',
        components: {
            main: Thread,
            sidebar: Sidebar
        }
    }
]

const router = new Router({
    mode: 'history',
    routes,
    scrollBehavior (to, from, savedPosition) {
        return savedPosition ? savedPosition : { x: 0, y: 0}
    }
})

export default router<|endoftext|>


<commit_before>/** @license
* Signals.js <https://github.com/webadvanced/signals.js>
* Released under the MIT license
* Author: Web Advanced
* Version: 0.0.1
*/

/**
* @namespace Signals Namespace - A lightweight (1k minified) pure JavaScript PubSub library
* @name signals
*/
var signals = (function (global, undefined) {
	"use strict";
    var evts = [],
        makeObservable,
        subscribeToSignal,
        takeAction,
		getSignalType,
		fire,
		unload;
	/**
	* Private function that makes the given signal observable.
	*
- (signals are an arbitrary string)
	* @private
	* @name makeObservable
	* @param {string} [signal] Name of the signal. (default = 'any').
	*/
    makeObservable = function (signal) {
        var signalType = getSignalType(signal);
        if (evts[signalType] === undefined) {
            evts[signalType] = [];
        }
    };
	/**
	* Private function that subscribes a listener to a signal.
	*
- (signals are an arbitrary string)
	* @private
	* @name subscribeToSignal
	* @param {string} [signal] Name of the observable signal. (default = 'any').
	* @param {Function} [fn] Callback function bound to the signal.
	* @param {Object} [context] Context on which listener will be executed (object that should represent the `this`. (default = window)
	*/
    subscribeToSignal = function (signal, fn, context) {
		var signalType = getSignalType(signal);
		evts[signalType].push({callback: fn, obj: context || global});
    };
	/**
	* Private function that handles the execution of Listeners for a given Signal or unsubscribe the Listener from the Signal
	* @private
	* @name takeAction
	* @param {string} [action] The action the function should take with the given arguments.
	* @param {string} [signal] Name of the signal. (default = 'any').
	* @param {Object} [arg] The args that will be passed to the Listeners or the function to be unsubscribed.
	*/
    takeAction = function (action, signal, arg) {
        var signalType = getSignalType(signal),
            actions = evts[signalType],
            i = 0,
            l,
			takeAction;
        if (actions === undefined) {
            return;
        }
		if (action === 'broadcast') {
			takeAction = fire;
		} else {
			takeAction = unload;
		}
        l = actions.length;
        for (i; i < l; i += 1) {
            takeAction(actions[i], arg, actions, i);
        }
    };
	/**
	* Private function that fires off a Listener.
	* @private
	* @name fire
	* @param {Object} [listener] The object that holds a callback and executing context.
	* @param {Object} [arg] The args that will be passed to the Listener.
	*/
	fire = function (listener, arg) {
		var ctx = listener.obj,
			fn = listener.callback;
		global.setTimeout(function () { fn.call(ctx, arg); }, 0);
	};
	/**
	* Private function that will unsubscribe a function from the supplied Signal.
	* @private
	* @name unload
	* @param {Object} [listener] The object that holds a callback and executing context.
	* @param {Function} [arg] The Function to be removed from the Signal.
	* @param {Array} [actions] Collection of subscribers for a signal.
	* @param {Number} [i] Index in the actions collection to be spliced out of the array.
	*/
	unload = function (listener, arg, actions, i) {
		if (listener !== undefined && listener.callback === arg) {
			actions.splice(i, 1);
        }
	};
	/**
	* Private function that sets the signal.
	* @private
	* @name getSignalType
	* @param {string} [signal] The Signal.
	*/
    getSignalType = function (signal) {
        /**
		* If signal is undefined, set signal to 'any'.
		* @signal string
		* @private
		*/
		return signal || 'any';
    };

    return {
		/**
		* Add a Listener to the given Signal.
		* @param {string} [signal] The signal.
		* @param {Function} Listener that should be added to the Signal.
		* @param {Object} [context] Context on which the listener will be executed (object that should represent the `this`. (default = window)
		*/
        subscribe: function (signal, fn, context) {
            makeObservable(signal);
            subscribeToSignal(signal, fn, context);
        },
		/**
		* Broadcast to all listeners of the given signal to execute.
		* @param {string} [signal] The signal.
		* @param {Object} Will be passed to each function as the argument.
		*/
        broadcast: function (signal, arg) {
            takeAction('broadcast', signal, arg);
        },
		/**
		* Remove a listener from the given signal.
		* @param {string} [signal] The signal.
		* @param {Function} Function that should be removed.
		*/
        unsubscribe: function (signal, fn) {
            takeAction('unsubscribe', signal, fn);
        },
		/**
		* Check is Signal is observable.
		* @name isObservable
		* @param {string} [signal] The signal.
		* @return {boolean} if signal is observable.
		*/
        isObservable: function (signal) {
            var signalType = getSignalType(signal);
            return evts[signalType] !== undefined;
        },
		/**
		* Gets the count of Listeners for the given Signal.
		* @name listenerCount
		* @param {string} [signal] The signal.
		* @return {Number} Number of Listeners. (default = 0).
		*/
        listenerCount: function (signal) {
            var signalType = getSignalType(signal),
                actions = evts[signalType];
            return actions !== undefined ? actions.length : 0;
        }
    };
}(this));<commit_msg>Updated comments is signals.js<commit_after>/** @license
* Signals.js <https://github.com/webadvanced/signals.js>
* Released under the MIT license
* Author: Web Advanced
* Version: 0.0.1
*/

/**
* @namespace Signals Namespace - A lightweight (1k minified) pure JavaScript PubSub library
* @name signals
*/
var signals = (function (global, undefined) {
	"use strict";
    var evts = [],
        makeObservable,
        subscribeToSignal,
        takeAction,
		getSignalType,
		fire,
		unload;
	/**
	* Private function that makes the given signal observable.
	*
- (signals are an arbitrary string)
	* @private
	* @name makeObservable
	* @param {string} [signal] Name of the signal. (default = 'any').
	*/
    makeObservable = function (signal) {
        var signalType = getSignalType(signal);
        if (evts[signalType] === undefined) {
            evts[signalType] = [];
        }
    };
	/**
	* Private function that subscribes a listener to a signal.
	*
- (signals are an arbitrary string)
	* @private
	* @name subscribeToSignal
	* @param {string} [signal] Name of the observable signal. (default = 'any').
	* @param {Function} [fn] Callback function bound to the signal.
	* @param {Object} [context] Context on which listener will be executed (object that should represent the `this`. (default = window)
	*/
    subscribeToSignal = function (signal, fn, context) {
		var signalType = getSignalType(signal);
		evts[signalType].push({callback: fn, obj: context || global});
    };
	/**
	* Private function that handles the execution of Listeners for a given Signal or unsubscribe the Listener from the Signal
	* @private
	* @name takeAction
	* @param {string} [action] The action the function should take with the given arguments.
	* @param {string} [signal] Name of the signal. (default = 'any').
	* @param {Object} [arg] The args that will be passed to the Listeners or the function to be unsubscribed.
	*/
    takeAction = function (action, signal, arg) {
        var signalType = getSignalType(signal),
            actions = evts[signalType],
            i = 0,
            l,
			takeAction;
        if (actions === undefined) {
            return;
        }
		if (action === 'broadcast') {
			takeAction = fire;
		} else {
			takeAction = unload;
		}
        l = actions.length;
        for (i; i < l; i += 1) {
            takeAction(actions[i], arg, actions, i);
        }
    };
	/**
	* Private function that fires off a Listener.
	* @private
	* @name fire
	* @param {Object} [listener] The object that holds a callback and executing context.
	* @param {Object} [arg] The args that will be passed to the Listener.
	*/
	fire = function (listener, arg) {
		var ctx = listener.obj,
			fn = listener.callback;
		global.setTimeout(function () { fn.call(ctx, arg); }, 0);
	};
	/**
	* Private function that will unsubscribe a function from the supplied Signal.
	* @private
	* @name unload
	* @param {Object} [listener] The object that holds a callback and executing context.
	* @param {Function} [arg] The Function to be removed from the Signal.
	* @param {Array} [actions] Collection of subscribers for a signal.
	* @param {Number} [i] Index in the actions collection to be spliced out of the array.
	*/
	unload = function (listener, arg, actions, i) {
		if (listener !== undefined && listener.callback === arg) {
			actions.splice(i, 1);
        }
	};
	/**
	* Private function that sets the signal.
	* @private
	* @name getSignalType
	* @param {string} [signal] The Signal.
	*/
    getSignalType = function (signal) {
        /**
		* If signal is undefined, set signal to 'any'.
		* @signal string
		* @private
		*/
		return signal || 'any';
    };

    return {
		/**
		* Add a Listener to the given Signal.
		* @name signals.subscribe
		* @param {string} [signal] The signal.
		* @param {Function} Listener that should be added to the Signal.
		* @param {Object} [context] Context on which the listener will be executed (object that should represent the `this`. (default = window)
		*/
        subscribe: function (signal, fn, context) {
            makeObservable(signal);
            subscribeToSignal(signal, fn, context);
        },
		/**
		* Broadcast to all listeners of the given signal to execute.
		* @name signals.broadcast
		* @param {string} [signal] The signal.
		* @param {Object} Will be passed to each function as the argument.
		*/
        broadcast: function (signal, arg) {
            takeAction('broadcast', signal, arg);
        },
		/**
		* Remove a listener from the given signal.
		* @name signals.unsubscribe
		* @param {string} [signal] The signal.
		* @param {Function} Function that should be removed.
		*/
        unsubscribe: function (signal, fn) {
            takeAction('unsubscribe', signal, fn);
        },
		/**
		* Check is Signal is observable.
		* @name signals.isObservable
		* @param {string} [signal] The signal.
		* @return {boolean} if signal is observable.
		*/
        isObservable: function (signal) {
            var signalType = getSignalType(signal);
            return evts[signalType] !== undefined;
        },
		/**
		* Gets the count of Listeners for the given Signal.
		* @name signals.listenerCount
		* @param {string} [signal] The signal.
		* @return {Number} Number of Listeners. (default = 0).
		*/
        listenerCount: function (signal) {
            var signalType = getSignalType(signal),
                actions = evts[signalType];
            return actions !== undefined ? actions.length : 0;
        }
    };
}(this));<|endoftext|>


<commit_before>chrome.runtime.sendMessage({info: "exportDataPageLoaded"}, function(response) {
    var exportedDataTextarea = document.getElementById("exportedDataTextarea");

    if (response.data.dataType === "json") {
        exportedDataTextarea.innerText = JSON.stringify(response.data.dataRecords);
    } else if (response.data.dataType === "csv") {
    }
});
<commit_msg>Implement export to CSV.<commit_after>function convertToCSV(dataRecords) {
    var dataRecordsLength = dataRecords.length,
        csvArray = [];

    for (var i=0; i < dataRecordsLength; i++) {
        var keys = Object.keys(dataRecords[i]),
            keysLength = keys.length,
            values = [];

        for (var j=0; j < keysLength; j++)  {
            var value = '"' + dataRecords[i][keys[j]].value + '"';
            values.push(value);
        }

        csvArray.push(values.join(","));
    }

    return csvArray.join("\n");
}

chrome.runtime.sendMessage({info: "exportDataPageLoaded"}, function(response) {
    var exportedDataTextarea = document.getElementById("exportedDataTextarea");

    if (response.data.dataType === "json") {
        exportedDataTextarea.innerText = JSON.stringify(response.data.dataRecords);
    } else if (response.data.dataType === "csv") {
        exportedDataTextarea.innerText = convertToCSV(response.data.dataRecords);
    }
});
<|endoftext|>


<commit_before>(function () {
  'use strict';

  function debug() {
    console.log(arguments);
  }

  function skip() {}

  var states = {
    PENDING: 0,
    FULFILLED: 1,
    REJECTED: 2
  };

  var vPromise = function (fn) {
    this._state = states.PENDING;
    this.value = null;
    var that = this;

    var onFulfilled = function (resolve) {
      if (typeof resolve !== 'function') { // 2.2.1
        return;
      }

      if (that._state !== states.PENDING) {
        that._state = states.FULFILLED;
        resolve(that.value);
      }
    };

    var onReject = function (reject, reason) {
      if (typeof reject !== 'function') { // 2.2.1
        return;
      }
      if (that._state !== states.PENDING) {
        that._state = states.REJECTED;
        reject(reason);
      }
    };

    var handle = function (resolve, reject) {
      if (that._state === states.PENDING) {
        return;
      }

      try {
        fn(onFulfilled(resolve), onReject(reject));
      } catch (e) {
        debug(e);
      }
    };

    if (fn !== skip) {
      fn(function (value) {
        that.value = value;
      },
      function (reason) {
        that.reason = reason;
      });
    }

    this.then = function (resolve, reject) {
      if (that._state === states.PENDING) {
        return;
      }
      var next = new vPromise(fn);
      handle(resolve, reject, next);
      next._state = -1; // placeholder
      return next;
    };

    this.catch = function (fn) {
    };

    return this;
  };

  vPromise.resolve = function (value) {
    var skipped = new vPromise(skip);
    return doResolve(skipped, value);
  };

  function doResolve(skipped, value) {
    skipped._state = states.FULFILLED;
    skipped.value = value;
    return skipped;
  }

  vPromise.reject = function (reason) {
    var skipped = new vPromise(skip);
    return doReject(skipped, reason);
  };

  function doReject(skipped, reason) {
    skipped._state = states.REJECTED;
    skipped.reason = reason;
    return skipped;
  }

  if (typeof module != 'undefined') {
    module.exports = vPromise;
  }

}());
<commit_msg>Get 2.2.2.1 to pass<commit_after>(function () {
  'use strict';

  function debug() {
    console.log(arguments);
  }

  function skip() {}

  var states = {
    PENDING: 0,
    FULFILLED: 1,
    REJECTED: 2
  };

  var vPromise = function (fn) {
    this._state = states.PENDING;
    this.value = null;
    var that = this;

    var onFulfilled = function (resolve) {
      if (typeof resolve !== 'function') { // 2.2.1
        return;
      }

      if (that._state !== states.PENDING) {
        that._state = states.FULFILLED;
        resolve(that.value);
      }
    };

    var onReject = function (reject, reason) {
      if (typeof reject !== 'function') { // 2.2.1
        return;
      }
      if (that._state !== states.PENDING) {
        that._state = states.REJECTED;
        reject(reason);
      }
    };

    var handle = function (resolve, reject) {
      if (that._state === states.PENDING) {
        return;
      }

      try {
        fn(onFulfilled(resolve), onReject(reject));
      } catch (e) {
        debug(e);
      }
    };

    if (fn !== skip) {
      fn(function (value) {
        that.value = value;
        that._resolve(value);
      },
      function (reason) {
        that.reason = reason;
      });
    }

    this.then = function (resolve, reject) {
      if (that._state === states.PENDING) {
        that._resolve = resolve;
        that._reject = reject;
        return;
      }
      var next = new vPromise(fn);
      handle(resolve, reject, next);
      next._state = -1; // placeholder
      return next;
    };

    this.catch = function (fn) {
    };

    return this;
  };

  vPromise.resolve = function (value) {
    var skipped = new vPromise(skip);
    return doResolve(skipped, value);
  };

  function doResolve(skipped, value) {
    skipped._state = states.FULFILLED;
    skipped.value = value;
    return skipped;
  }

  vPromise.reject = function (reason) {
    var skipped = new vPromise(skip);
    return doReject(skipped, reason);
  };

  function doReject(skipped, reason) {
    skipped._state = states.REJECTED;
    skipped.reason = reason;
    return skipped;
  }

  if (typeof module != 'undefined') {
    module.exports = vPromise;
  }

}());
<|endoftext|>


<commit_before>import { app, BrowserWindow } from 'electron'

let mainWindow = null

app.on('window-all-closed', () => {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

app.on('ready', () => {
    // Initialize the window to our specified dimensions
    mainWindow = new BrowserWindow({ width: 1200, height: 900, icon: __dirname + '/static/pi_logo.png', frame: true});

    // Tell Electron where to load the entry point from
    mainWindow.loadURL('file://' + __dirname + '/app/app.html');

    // Clear out the main window when the app is closed
    mainWindow.on('closed', () => {
        mainWindow = null;
    });
});
<commit_msg>changes window size to the monitors we will use<commit_after>import { app, BrowserWindow } from 'electron'

let mainWindow = null

app.on('window-all-closed', () => {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

app.on('ready', () => {
    // Initialize the window to our specified dimensions
    mainWindow = new BrowserWindow({ width: 1024, height: 768, icon: __dirname + '/static/pi_logo.png', frame: true});

    // Tell Electron where to load the entry point from
    mainWindow.loadURL('file://' + __dirname + '/app/app.html');

    // Clear out the main window when the app is closed
    mainWindow.on('closed', () => {
        mainWindow = null;
    });
});
<|endoftext|>


<commit_before>process.env.TEST_ENV = true
const Foobar = require('./__mocks__/Foobar.js')
const FoobarClass = require('./__mocks__/FoobarClass.js')
const mongoose = require('mongoose')
const dbName = 'test_int_base'
const CON_OPTIONS = {
  useNewUrlParser: true,
  useUnifiedTopology: true
}

describe('Int::Base Database', function () {
  beforeAll(async function () {
    await mongoose.connect(`mongodb://localhost:27017/${dbName}`, CON_OPTIONS)
    await mongoose.connection.db.dropDatabase()
  })
  it('initializes correctly', async function () {
    const initData = { foo: 'qgfdew4' }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    expect(foobar.data).toEqual(JSON.parse(JSON.stringify(doc.toObject())))
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.isSaved()).toEqual(true)
    await doc.remove()
  })
  it('saves', async function () {
    const data = {
      foo: '349y5hjt',
      baz: 666
    }
    const foobar = new FoobarClass(data)
    expect(foobar.isSaved()).toEqual(false)
    await foobar.save()
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.isSaved()).toEqual(true)
    const found = Foobar.findOne(data).exec()
    expect(found).toBeDefined()
  })
  it('gets', async function () {
    const initData = { foo: 'q352tew4', baz: 235 }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = await FoobarClass.get(doc._id.toHexString())
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.data).toEqual(JSON.parse(JSON.stringify(doc.toObject())))
    for (const key in initData) {
      expect(foobar[key]).toEqual(initData[key])
    }
  })
  it('deletes', async function () {
    const initFoobar = new Foobar({ foo: 'abc' })
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    await foobar.delete()
    const queried = await Foobar.findById(doc._id.toHexString())
    expect(queried).toBeNull()
  })
  it('gets many', async function () {
    const a = new Foobar({ foo: 'a' })
    const b = new Foobar({ foo: 'b' })
    const saves = await Promise.all([ a.save(), b.save() ])
    const [ id1, id2 ] = saves.map(doc => doc._id.toHexString())
    const classes = await FoobarClass.getMany([ id1, id2 ])
    expect(classes.length).toEqual(2)
    for (const item of classes) {
      expect(item).toBeInstanceOf(FoobarClass)
    }
    expect(classes[0].foo).toEqual('a')
    expect(classes[1].foo).toEqual('b')
  })
  it('updates', async function () {
    const initData = { foo: 'exquisite' }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    const newFooValue = 'changzz'
    foobar.foo = newFooValue
    await foobar.save()
    const found = await Foobar.findById(initFoobar.id)
    expect(found.foo).toEqual(newFooValue)
  })
  it('deletes a key on undefined', async function () {
    const initData = { foo: 'w49ti093u4j', baz: 987 }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    foobar.foo = undefined
    await foobar.save()
    const found = await Foobar.findById(initFoobar.id).lean().exec()
    expect(Object.keys(found)).not.toContain('foo')
  })
  it(`doesn't add keys after update`, async function () {
    const initData = { foo: 'w49t4j', baz: 9876 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'abc'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(found.nullField).toBeUndefined()
  })
  it(`doesn't set object field when undefined`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).not.toContain('object')
  })
  it(`doesn't set object field when undefined after update`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'zack'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).not.toContain('object')
  })
  it(`sets default empty array`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    expect(foobar.array).toBeInstanceOf(Array)
    expect(foobar.array).toHaveLength(0)
  })
  it(`doesn't remove the array when updated`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'qwe'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).toContain('array')
  })
  it('autocasts to ObjectId for strings', async function () {
    const initData = { objectId: new mongoose.Types.ObjectId().toHexString() }
    const foobar = new FoobarClass(initData)
    expect(foobar.save()).resolves.toEqual(foobar)
  })
  afterAll(async function () {
    await mongoose.connection.db.dropDatabase()
    await mongoose.connection.close()
  })
})
<commit_msg>Add int test for Base.getBy database<commit_after>process.env.TEST_ENV = true
const Foobar = require('./__mocks__/Foobar.js')
const FoobarClass = require('./__mocks__/FoobarClass.js')
const mongoose = require('mongoose')
const dbName = 'test_int_base'
const CON_OPTIONS = {
  useNewUrlParser: true,
  useUnifiedTopology: true
}

describe('Int::Base Database', function () {
  beforeAll(async function () {
    await mongoose.connect(`mongodb://localhost:27017/${dbName}`, CON_OPTIONS)
    await mongoose.connection.db.dropDatabase()
  })
  it('initializes correctly', async function () {
    const initData = { foo: 'qgfdew4' }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    expect(foobar.data).toEqual(JSON.parse(JSON.stringify(doc.toObject())))
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.isSaved()).toEqual(true)
    await doc.remove()
  })
  it('saves', async function () {
    const data = {
      foo: '349y5hjt',
      baz: 666
    }
    const foobar = new FoobarClass(data)
    expect(foobar.isSaved()).toEqual(false)
    await foobar.save()
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.isSaved()).toEqual(true)
    const found = Foobar.findOne(data).exec()
    expect(found).toBeDefined()
  })
  it('gets', async function () {
    const initData = { foo: 'q352tew4', baz: 235 }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = await FoobarClass.get(doc._id.toHexString())
    expect(foobar.document).toBeInstanceOf(mongoose.Model)
    expect(foobar.data).toEqual(JSON.parse(JSON.stringify(doc.toObject())))
    for (const key in initData) {
      expect(foobar[key]).toEqual(initData[key])
    }
  })
  it('getsBy', async function () {
    const initData1 = {
      foo: 'baz',
      baz: 1
    }
    const initData2 = {
      foo: 'bfgjz',
      baz: 2
    }
    const initData3 = {
      foo: 'bfgjz',
      baz: 3
    }
    await new Foobar(initData1).save()
    await new Foobar(initData2).save()
    await new Foobar(initData3).save()
    const found = await FoobarClass.getBy('foo', 'bfgjz')
    expect(found.data).toEqual(expect.objectContaining(initData2))
  })
  it('deletes', async function () {
    const initFoobar = new Foobar({ foo: 'abc' })
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    await foobar.delete()
    const queried = await Foobar.findById(doc._id.toHexString())
    expect(queried).toBeNull()
  })
  it('gets many', async function () {
    const a = new Foobar({ foo: 'a' })
    const b = new Foobar({ foo: 'b' })
    const saves = await Promise.all([ a.save(), b.save() ])
    const [ id1, id2 ] = saves.map(doc => doc._id.toHexString())
    const classes = await FoobarClass.getMany([ id1, id2 ])
    expect(classes.length).toEqual(2)
    for (const item of classes) {
      expect(item).toBeInstanceOf(FoobarClass)
    }
    expect(classes[0].foo).toEqual('a')
    expect(classes[1].foo).toEqual('b')
  })
  it('updates', async function () {
    const initData = { foo: 'exquisite' }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    const newFooValue = 'changzz'
    foobar.foo = newFooValue
    await foobar.save()
    const found = await Foobar.findById(initFoobar.id)
    expect(found.foo).toEqual(newFooValue)
  })
  it('deletes a key on undefined', async function () {
    const initData = { foo: 'w49ti093u4j', baz: 987 }
    const initFoobar = new Foobar(initData)
    const doc = await initFoobar.save()
    const foobar = new FoobarClass(doc)
    foobar.foo = undefined
    await foobar.save()
    const found = await Foobar.findById(initFoobar.id).lean().exec()
    expect(Object.keys(found)).not.toContain('foo')
  })
  it(`doesn't add keys after update`, async function () {
    const initData = { foo: 'w49t4j', baz: 9876 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'abc'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(found.nullField).toBeUndefined()
  })
  it(`doesn't set object field when undefined`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).not.toContain('object')
  })
  it(`doesn't set object field when undefined after update`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'zack'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).not.toContain('object')
  })
  it(`sets default empty array`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    expect(foobar.array).toBeInstanceOf(Array)
    expect(foobar.array).toHaveLength(0)
  })
  it(`doesn't remove the array when updated`, async function () {
    const initData = { foo: 'w44j', baz: 13579 }
    const foobar = new FoobarClass(initData)
    const saved = await foobar.save()
    foobar.foo = 'qwe'
    await foobar.save()
    const found = await Foobar.findById(saved.id).lean().exec()
    expect(Object.keys(found)).toContain('array')
  })
  it('autocasts to ObjectId for strings', async function () {
    const initData = { objectId: new mongoose.Types.ObjectId().toHexString() }
    const foobar = new FoobarClass(initData)
    expect(foobar.save()).resolves.toEqual(foobar)
  })
  afterAll(async function () {
    await mongoose.connection.db.dropDatabase()
    await mongoose.connection.close()
  })
})
<|endoftext|>


<commit_before>import React from 'react/addons';

import Board       from '../../models/board';
import BoardAction from '../../actions/board';
import Dialog      from '../../components/dialog';
/**
 *
 */
export default React.createClass({
    mixins: [ React.addons.PureRenderMixin, React.addons.LinkedStateMixin ],

    propTypes: {
        board: (props) => {
            if(!props.board instanceof Board) throw new Error();
        },
        onDismiss: React.PropTypes.func.isRequired
    },

    submit(event) {
        event.preventDefault();
        return this.props.onDismiss();
    },

    hide() {
        BoardAction.revokeAccessCode({ id: this.props.board.id });
    },

    share() {
        BoardAction.generateAccessCode({ id: this.props.board.id });
    },

    render() {
        let id   = this.props.board.id;
        let code = this.props.board.accessCode;

        let sharedURL = code !== null && code.length > 0
            ? location.host + '/boards/' + id + '/access/' + code + ''
            : '';

        let shareButtonClass = sharedURL.length > 0 ? 'neutral' : 'secondary';
        let shareButtonClick = sharedURL.length > 0 ? this.hide : this.share;

        let shareButton = (
            <button className={`btn-${shareButtonClass}`}
                    onClick={shareButtonClick}>
                { sharedURL.length > 0 ? 'Hide' : 'Share' }
            </button>
        );

        return (
            <Dialog className="dialog-edit-board"
                    onDismiss={this.props.onDismiss}>

                    Share board

                    Shared link

                        <input name="board-share" placeholder="Shared link"
                               readOnly={true} value={sharedURL} tabIndex={-1}/>
                        {shareButton}

                    <button className="btn-primary" onClick={this.submit}>
                        Done
                    </button>

            </Dialog>
        );
    }
});
<commit_msg>Select input text in share dialog on click<commit_after>import React from 'react/addons';

import Board       from '../../models/board';
import BoardAction from '../../actions/board';
import Dialog      from '../../components/dialog';
/**
 *
 */
export default React.createClass({
    mixins: [ React.addons.PureRenderMixin, React.addons.LinkedStateMixin ],

    propTypes: {
        board: (props) => {
            if(!props.board instanceof Board) throw new Error();
        },
        onDismiss: React.PropTypes.func.isRequired
    },

    componentDidUpdate() {
        console.log("componentDidUpdate");
        this.highlight();
    },

    submit(event) {
        event.preventDefault();
        return this.props.onDismiss();
    },

    hide() {
        BoardAction.revokeAccessCode({ id: this.props.board.id });
    },

    share() {
        BoardAction.generateAccessCode({ id: this.props.board.id });
        this.highlight();
    },

    highlight() {
        let input = this.refs.shareInput.getDOMNode();
        input.setSelectionRange(0, input.value.length);
    },

    render() {
        let id   = this.props.board.id;
        let code = this.props.board.accessCode;

        let sharedURL = code !== null && code.length > 0
            ? location.host + '/boards/' + id + '/access/' + code + ''
            : '';

        let shareButtonClass = sharedURL.length > 0 ? 'neutral' : 'secondary';
        let shareButtonClick = sharedURL.length > 0 ? this.hide : this.share;

        let shareButton = (
            <button className={`btn-${shareButtonClass}`}
                    onClick={shareButtonClick}>
                { sharedURL.length > 0 ? 'Hide' : 'Share' }
            </button>
        );

        return (
            <Dialog className="dialog-edit-board"
                    onDismiss={this.props.onDismiss}>

                    Share board

                    Shared link

                        <input ref="shareInput"
                               onClick={this.highlight}
                               name="board-share" placeholder="Shared link"
                               readOnly={true} value={sharedURL} tabIndex={-1}/>
                        {shareButton}

                    <button className="btn-primary" onClick={this.submit}>
                        Done
                    </button>

            </Dialog>
        );
    }
});
<|endoftext|>


<commit_before>var gLogLimit = 500;
var gLogCount = 0;

function clone(obj) {
  return $.extend({}, obj);
}

function getURLParameter(name) {
  return decodeURI(
    (RegExp(name + "=" + "(.+?)(&|$)").exec(location.search) || [, null])[1]
  );
}

function log(api, type, msg) {
  var $mlog = $("#commLog");
  gLogCount++;
  if (gLogCount > gLogLimit) {
    // remove first child
    $mlog.children(":first").remove();
  }

  color = "black";
  bodyColor = "black";
  if (type == "error") {
    color = "red"
    bodyColor = "red";
  }
  if (api == "rest") {
    color = "blue";
  }
  if (api == "socket") {
    color = "green";
  }
  if (typeof(msg) == "object") {
    msg = JSON.stringify(msg);
  }
  var disp = "
";
  disp += "" + api + "-";
  disp += "" + type + ": ";
  disp += "" + msg + "";
  disp += "
";
  $mlog.append(disp).scrollTop($mlog[0].scrollHeight - $mlog.height());
}

function showError(msg) {
  $("#errorMessage").css("display", "block");
  $("#errorMessage").text(msg);
}

function hideError() {
  $("#errorMessage").css("display", "none");
}

function setWhoTurn(gameId, whoTurn, profile) {
  $gamePlaying = $(".myGameId" + gameId);
  $turnSpan = $gamePlaying.find("#gameTurn");
  $turnSpan.removeClass("playerName" + whoTurn);
  if (whoTurn === "") {
    $turnSpan.text("");
    $gamePlaying.detach();
    $gamePlaying.prependTo("#gameDoneList");
  } else if (whoTurn === Env.user.oid) {
    $turnSpan.text("");
    $gamePlaying.detach();
    $gamePlaying.prependTo("#gameMyTurnList");
  } else {
    var name = profile.name;
    if (name.length === 0) {
      name = whoTurn;
    }
    $turnSpan.text(name.substr(0, 12) + "'s");
    $turnSpan.addClass("playerName" + whoTurn);  // helps with name changes
    $gamePlaying.detach();
    $gamePlaying.appendTo("#gameOppTurnList");
  }
}

function setMyGames(gameList) {
  $(".activeGame").remove();
  for (gameId in gameList) {
    var $newGame = $("#gameTemplate").clone();
    $newGame.find("#gameName").text(gameList[gameId].name.substr(0, 6) + "-" + gameId.substr(0, 4) + "..");
    var game = gameList[gameId];
    $newGame.addClass("myGameId" + gameId);
    $newGame.addClass("activeGame");
    $newGame.attr("gameId", gameId);
    $newGame.attr("gameName", gameList[gameId].name);
    $newGame.css("display", "block");

    $newGame.find("#myGameJoin").click(function () {
      var gameId = $(this).parent().attr("gameId");
      var gameName = $(this).parent().attr("gameName");
      gameInit(gameName, gameId);
    });
    $newGame.find("#myGameRemove").click(function (event) {
      $(event.target).parent().remove();
      var data = clone(Env.baseParams);
      data.cmd = "game.leave";
      data.gameId = $(this).parent().attr("gameId");
      sendWs(data);
    });

    // start it in the game list and let setWhoTurn sort it
    $("#gameMyTurnList").append($newGame);

    setWhoTurn(gameId, game.whoTurn, game.players[game.whoTurn]);
  }
}

var ws = new ReconnectingWebSocket();
//        ws.debug = true;
ws.onopen = function (evt) {
  log("socket", "onopen", Env.socketUrl);
  shellyInit();
}
ws.onmessage = function (evt) {
  var received_msg = evt.data;
  log("socket", "onmessage", evt.data);
  var msg = JSON.parse(evt.data);
  processEvent(msg, "socket");
}
ws.onclose = function (evt) {
  log("socket", "onclose", JSON.stringify(evt));
}
ws.onerror = function (evt) {
  log("socket", "error", JSON.stringify(evt));
}

// assumes global ws object
function sendWs(data) {
  var obj = {};
  obj.session = Env.session;
  var obj = $.extend(obj, data);
  var msg = JSON.stringify(obj);
  log("socket", "send", msg);
  ws.send(msg);
}

function sendCmd(cmd, data) {
  var obj = {};
  obj.session = Env.session;
  obj.cmd = cmd;
  var obj = $.extend(obj, data);
  try {
    sendWs(obj);
  } catch(e) {
    log("socket", "error", e.toString())
  }
}

function sendRestCmd(cmd, data, cb) {
  var obj = {};
  obj.session = Env.session;
  obj.cmd = cmd;
  var obj = $.extend(obj, data);
  log("rest", "send", obj);
  $.ajax
    ({
      type: "POST",
      url: Env.restUrl,
      async: true,
      contentType: "application/json",
      dataType: "json",
      data: JSON.stringify(obj),
      success: function (res, status) {
        log("rest", "recv", res);
        // SWD just take first message for now
        cb(0, res[0]);
      },
      error: function (xhr, textStatus, errorThrown) {
        log("rest", "error", xhr.responseText);
        cb(1, textStatus);
      }
    })
}

/***********************
 * Message bank functions
***********************/
var gMessageCount = 0;
var gMessageChannel = "lobby:0";

function messageInit(channel)
{
  gMessageChannel = channel;
  $("#chatInput").bind('keypress', function(e){
    if ( e.keyCode == 13 ) {
      sendMessage($(this).val());
      $(this).val("");
    }
  });
}

function messageReset() {
  gMessageCount = 0;
  $(".messageObject").remove();
}

function addMessage(data) {
  if(data.channel !== gMessageChannel) {
    // drop it for now
    return;
  }

  var $mlog = $("#messageLog");
  gMessageCount++;
  if (gMessageCount > gLogLimit) {
    // remove first child
    $mlog.children(":first").remove();
  }

  color = "blue";
  bodyColor = "black";
  var name = data.name;
  if (data.from === Env.user.oid) {
    name = "you";
    color = "black";
  }
  var disp = "
";
  disp += "" + name + ": ";
  disp += "" + data.message + "";
  disp += "
";
  $mlog.append(disp).scrollTop($mlog[0].scrollHeight - $mlog.height());
}

function sendMessage(msg) {
  sendCmd("channel.send", {channel: gMessageChannel, message: msg});
}

function commInit()
{
  $("#showHideLog").click(function () {
    if ($(this).text() === "+") {
      $(this).text("-");
      $("#commLog").css("height", "200px");
    } else {
      $(this).text("+");
      $("#commLog").css("height", "0px");
    }
  });
}

/*
 * JavaScript Pretty Date
 * Copyright (c) 2011 John Resig (ejohn.org)
 * Licensed under the MIT and GPL licenses.
 */

// Takes an ISO time and returns a string representing how
// long ago the date represents.
function prettyDate(time){
//  console.log(new Date(time));
//  var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
  var date = new Date(time),
    diff = (((new Date()).getTime() - date.getTime()) / 1000),
    day_diff = Math.floor(diff / 86400);

  if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
    return;

  return day_diff == 0 && (
    diff < 2 && "1 second ago" ||
    diff < 60 && Math.round(diff) + " seconds ago" ||
      diff < 120 && "1 minute ago" ||
      diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
      diff < 7200 && "1 hour ago" ||
      diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
    day_diff == 1 && "Yesterday" ||
    day_diff < 7 && day_diff + " days ago" ||
    day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}<commit_msg>escape the comm and message display;<commit_after>var gLogLimit = 500;
var gLogCount = 0;

function clone(obj) {
  return $.extend({}, obj);
}

function getURLParameter(name) {
  return decodeURI(
    (RegExp(name + "=" + "(.+?)(&|$)").exec(location.search) || [, null])[1]
  );
}

function log(api, type, msg) {
  var $mlog = $("#commLog");
  gLogCount++;
  if (gLogCount > gLogLimit) {
    // remove first child
    $mlog.children(":first").remove();
  }

  color = "black";
  bodyColor = "black";
  if (type == "error") {
    color = "red"
    bodyColor = "red";
  }
  if (api == "rest") {
    color = "blue";
  }
  if (api == "socket") {
    color = "green";
  }
  if (typeof(msg) == "object") {
    msg = JSON.stringify(msg);
  }
  var disp = "
";
  disp += "" + api + "-";
  disp += "" + type + ": ";
  disp += "";
  disp += "
";
  $disp = $(disp);
  $disp.find("#cText").text(msg);
  $mlog.append($disp).scrollTop($mlog[0].scrollHeight - $mlog.height());
}

function showError(msg) {
  $("#errorMessage").css("display", "block");
  $("#errorMessage").text(msg);
}

function hideError() {
  $("#errorMessage").css("display", "none");
}

function setWhoTurn(gameId, whoTurn, profile) {
  $gamePlaying = $(".myGameId" + gameId);
  $turnSpan = $gamePlaying.find("#gameTurn");
  $turnSpan.removeClass("playerName" + whoTurn);
  if (whoTurn === "") {
    $turnSpan.text("");
    $gamePlaying.detach();
    $gamePlaying.prependTo("#gameDoneList");
  } else if (whoTurn === Env.user.oid) {
    $turnSpan.text("");
    $gamePlaying.detach();
    $gamePlaying.prependTo("#gameMyTurnList");
  } else {
    var name = profile.name;
    if (name.length === 0) {
      name = whoTurn;
    }
    $turnSpan.text(name.substr(0, 12) + "'s");
    $turnSpan.addClass("playerName" + whoTurn);  // helps with name changes
    $gamePlaying.detach();
    $gamePlaying.appendTo("#gameOppTurnList");
  }
}

function setMyGames(gameList) {
  $(".activeGame").remove();
  for (gameId in gameList) {
    var $newGame = $("#gameTemplate").clone();
    $newGame.find("#gameName").text(gameList[gameId].name.substr(0, 6) + "-" + gameId.substr(0, 4) + "..");
    var game = gameList[gameId];
    $newGame.addClass("myGameId" + gameId);
    $newGame.addClass("activeGame");
    $newGame.attr("gameId", gameId);
    $newGame.attr("gameName", gameList[gameId].name);
    $newGame.css("display", "block");

    $newGame.find("#myGameJoin").click(function () {
      var gameId = $(this).parent().attr("gameId");
      var gameName = $(this).parent().attr("gameName");
      gameInit(gameName, gameId);
    });
    $newGame.find("#myGameRemove").click(function (event) {
      $(event.target).parent().remove();
      var data = clone(Env.baseParams);
      data.cmd = "game.leave";
      data.gameId = $(this).parent().attr("gameId");
      sendWs(data);
    });

    // start it in the game list and let setWhoTurn sort it
    $("#gameMyTurnList").append($newGame);

    setWhoTurn(gameId, game.whoTurn, game.players[game.whoTurn]);
  }
}

var ws = new ReconnectingWebSocket();
//        ws.debug = true;
ws.onopen = function (evt) {
  log("socket", "onopen", Env.socketUrl);
  shellyInit();
}
ws.onmessage = function (evt) {
  var received_msg = evt.data;
  log("socket", "onmessage", evt.data);
  var msg = JSON.parse(evt.data);
  processEvent(msg, "socket");
}
ws.onclose = function (evt) {
  log("socket", "onclose", JSON.stringify(evt));
}
ws.onerror = function (evt) {
  log("socket", "error", JSON.stringify(evt));
}

// assumes global ws object
function sendWs(data) {
  var obj = {};
  obj.session = Env.session;
  var obj = $.extend(obj, data);
  var msg = JSON.stringify(obj);
  log("socket", "send", msg);
  ws.send(msg);
}

function sendCmd(cmd, data) {
  var obj = {};
  obj.session = Env.session;
  obj.cmd = cmd;
  var obj = $.extend(obj, data);
  try {
    sendWs(obj);
  } catch(e) {
    log("socket", "error", e.toString())
  }
}

function sendRestCmd(cmd, data, cb) {
  var obj = {};
  obj.session = Env.session;
  obj.cmd = cmd;
  var obj = $.extend(obj, data);
  log("rest", "send", obj);
  $.ajax
    ({
      type: "POST",
      url: Env.restUrl,
      async: true,
      contentType: "application/json",
      dataType: "json",
      data: JSON.stringify(obj),
      success: function (res, status) {
        log("rest", "recv", res);
        // SWD just take first message for now
        cb(0, res[0]);
      },
      error: function (xhr, textStatus, errorThrown) {
        log("rest", "error", xhr.responseText);
        cb(1, textStatus);
      }
    })
}

/***********************
 * Message bank functions
***********************/
var gMessageCount = 0;
var gMessageChannel = "lobby:0";

function messageInit(channel)
{
  gMessageChannel = channel;
  $("#chatInput").bind('keypress', function(e){
    if ( e.keyCode == 13 ) {
      if($(this).val() !== "")
      {
        sendMessage($(this).val());
        $(this).val("");
      }
    }
  });
}

function messageReset() {
  gMessageCount = 0;
  $(".messageObject").remove();
}

function addMessage(data) {
  if(data.channel !== gMessageChannel) {
    // drop it for now
    return;
  }

  var $mlog = $("#messageLog");
  gMessageCount++;
  if (gMessageCount > gLogLimit) {
    // remove first child
    $mlog.children(":first").remove();
  }

  color = "blue";
  bodyColor = "black";
  var name = data.name;
  if (data.from === Env.user.oid) {
    name = "you";
    color = "black";
  }

  var disp = "
";
  disp += "" + name + ": ";
  disp += "";
  disp += "
";
  $disp = $(disp);
  $disp.find("#mText").text(data.message);

  $mlog.append($disp).scrollTop($mlog[0].scrollHeight - $mlog.height());
}

function sendMessage(msg) {
  sendCmd("channel.send", {channel: gMessageChannel, message: msg});
}

function commInit()
{
  $("#showHideLog").click(function () {
    if ($(this).text() === "+") {
      $(this).text("-");
      $("#commLog").css("height", "200px");
    } else {
      $(this).text("+");
      $("#commLog").css("height", "0px");
    }
  });
}

/*
 * JavaScript Pretty Date
 * Copyright (c) 2011 John Resig (ejohn.org)
 * Licensed under the MIT and GPL licenses.
 */

// Takes an ISO time and returns a string representing how
// long ago the date represents.
function prettyDate(time){
//  console.log(new Date(time));
//  var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
  var date = new Date(time),
    diff = (((new Date()).getTime() - date.getTime()) / 1000),
    day_diff = Math.floor(diff / 86400);

  if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
    return;

  return day_diff == 0 && (
    diff < 2 && "1 second ago" ||
    diff < 60 && Math.round(diff) + " seconds ago" ||
      diff < 120 && "1 minute ago" ||
      diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
      diff < 7200 && "1 hour ago" ||
      diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
    day_diff == 1 && "Yesterday" ||
    day_diff < 7 && day_diff + " days ago" ||
    day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}<|endoftext|>


<commit_before>define([
      'knockout'
    , '../util'
    , '../models/github_repo'
    , 'text!./github_repos_list.html'
    , './loading_bar'
], function(ko, util, GithubRepoModel, template) {
    function GithubReposListModel(params) {
        finalParams = $.extend({
              'action': (function(){})
            , 'columnSize': 4
            , 'pageSize': 20
            , 'reload': false
            , 'trigReload': undefined
            , 'ready': (function(){})
        }, params)
        debugger

        this.pageSize = finalParams['pageSize']

        this.messages = ko.observableArray()
        this.repos = ko.observableArray()
        this.loading = ko.observable(false)
        this.redirect = ko.observable()

        this.currentAccount = ko.observable()
        this.accounts = ko.computed(function() {
            var currentAccountStr = this.currentAccount(),
                list = $.unique(this.repos().map(function(repo) {
                    return repo.account()
                }))
            if(typeof(currentAccountStr) == 'undefined' || $.inArray(this.currentAccount(), list) === -1) {
                this.currentAccount(list[0])
            }
            return list
        }.bind(this))

        this.columnSize = util.param(finalParams['columnSize'])

        this.no_repos = ko.computed(function() {
            return (!this.loading()) && this.repos().length == 0
        }.bind(this))
        this.columnClass = ko.computed(function() {
            return "col-sm-" + this.columnSize()
        }.bind(this))

        this.action = finalParams['action']

        loadFrom = function(page) {
            this.loading(true)
            $.ajax("/github/projects.json",  {
                  'dataType': 'json'
                , 'data': {
                      'per_page': this.pageSize
                    , 'page': page
                }
            }).done(function(reposData) {
                if(typeof(reposData) == 'object' && 'redirect' in reposData) {
                    this.redirect(reposData['redirect'])
                    return
                }

                $(reposData['repos']).each(function(idx, repoData) {
                    this.repos.push(new GithubRepoModel({
                          'fullId': repoData['full_name']
                        , 'cloneUrl': repoData['clone_url']
                    }))
                }.bind(this))

                if(reposData['repos'].length >= this.pageSize) {
                    loadFrom(page + 1)
                } else {
                    this.loading(false)
                }
            }.bind(this)).fail(function(jqXHR, textStatus, errorThrown) {
                this.loading(false)
                util.ajax_fail(self.messages)(jqXHR, textStatus, errorThrown)
            })
        }.bind(this)

        this.clickHandler = function(repo) {
            this.action(repo)
        }.bind(this)
        this.reload = function() {
            this.repos([])
            loadFrom(1)
        }.bind(this)

        if(finalParams['reload']) {
            this.reload()
        }

        // TRIGGERS
        util.param(finalParams['trigReload']).subscribe(function() {
            this.reload()
        }.bind(this))
        finalParams['ready'](true)
    }

    ko.components.register('github-repos-list', {
        viewModel: GithubReposListModel, template: template,
    })

    return GithubReposListModel
})
<commit_msg>Revert accidental dev changes to github list<commit_after>define([
      'knockout'
    , '../util'
    , '../models/github_repo'
    , 'text!./github_repos_list.html'
    , './loading_bar'
], function(ko, util, GithubRepoModel, template) {
    function GithubReposListModel(params) {
        finalParams = $.extend({
              'action': (function(){})
            , 'columnSize': 4
            , 'pageSize': 20
            , 'reload': false
            , 'trigReload': undefined
            , 'ready': (function(){})
        }, params)

        this.pageSize = finalParams['pageSize']

        this.messages = ko.observableArray()
        this.repos = ko.observableArray()
        this.loading = ko.observable(false)

        this.currentAccount = ko.observable()
        this.accounts = ko.computed(function() {
            var currentAccountStr = this.currentAccount(),
                list = $.unique(this.repos().map(function(repo) {
                    return repo.account()
                }))
            if(typeof(currentAccountStr) == 'undefined' || $.inArray(this.currentAccount(), list) === -1) {
                this.currentAccount(list[0])
            }
            return list
        }.bind(this))

        this.columnSize = util.param(finalParams['columnSize'])

        this.no_repos = ko.computed(function() {
            return (!this.loading()) && this.repos().length == 0
        }.bind(this))
        this.columnClass = ko.computed(function() {
            return "col-sm-" + this.columnSize()
        }.bind(this))

        this.action = finalParams['action']

        loadFrom = function(page) {
            this.loading(true)
            $.ajax("/github/projects.json",  {
                  'dataType': 'json'
                , 'data': {
                      'per_page': this.pageSize
                    , 'page': page
                }
            }).done(function(reposData) {
                $(reposData['repos']).each(function(idx, repoData) {
                    this.repos.push(new GithubRepoModel({
                          'fullId': repoData['full_name']
                        , 'cloneUrl': repoData['clone_url']
                    }))
                }.bind(this))

                if(reposData['repos'].length >= this.pageSize) {
                    loadFrom(page + 1)
                } else {
                    this.loading(false)
                }
            }.bind(this)).fail(function(jqXHR, textStatus, errorThrown) {
                this.loading(false)
                util.ajax_fail(self.messages)(jqXHR, textStatus, errorThrown)
            })
        }.bind(this)

        this.clickHandler = function(repo) {
            this.action(repo)
        }.bind(this)
        this.reload = function() {
            this.repos([])
            loadFrom(1)
        }.bind(this)

        if(finalParams['reload']) {
            this.reload()
        }

        // TRIGGERS
        util.param(finalParams['trigReload']).subscribe(function() {
            this.reload()
        }.bind(this))
        finalParams['ready'](true)
    }

    ko.components.register('github-repos-list', {
        viewModel: GithubReposListModel, template: template,
    })

    return GithubReposListModel
})
<|endoftext|>


<commit_before>(function () {
	angular
		.module('docker-manager-ui.containers')
		.controller('ContainersCtrl', ContainersCtrl);

	ContainersCtrl.$inject = ['$scope', '$filter', 'ngTableParams', 'Containers'];
	function ContainersCtrl (  $scope,   $filter,   ngTableParams,   Containers) {
		var vm = $scope;

		//var _searching = undefined;

		/**
		 * Publish scope
		 */
		// Already loaded containers
		vm.containers = [];
		vm.params = {
			all: true,
			limit: 100
		};

		// Table configuration
		vm.tableParams = new ngTableParams({
			page: 1,
			count: 10,
			sorting: {
				Image: 'asc'
			}
		}, {
			total: 0,
			getData: function ($defer, params) {
				/*if (_searching) {
					// Already searching
					_searching.then($defer.resolve, $defer.reject);
					return;
				}*/

				// Habemus data
				console.log('Looking for containers at page (index %d, count %d) with sort', params.page(), params.count(), params.orderBy());
				var data = vm.containers;

				// Update total count
				params.total(data.length);

				// Sort
				var orderedData = params.sorting() ?
                    $filter('orderBy')(data, params.orderBy()) :
                    data;

				// Page
				if (orderedData.length > 0) {
					var start = (params.page() - 1) * params.count(),
						end = Math.min(orderedData.length, params.page() * params.count());
					orderedData = orderedData.slice(start, end);
				}

				$defer.resolve(orderedData);
			}
		});

		// Expose actions to views
		vm.search = search;
		vm.startAllContainers = startAllContainers;
		vm.stopAllContainers = stopAllContainers;
		vm.startContainer = startContainer;
		vm.stopContainer = stopContainer;
		vm.isStoppable = isStoppable;
		vm.isStartable = isStartable;

		// Watchs
		/*vm.$watch('params', function (newValue, oldValue) {
			console.log('Updating ngTable limit with form limit');
			//vm.tableParams.limit(vm.params.limit);
		});*/

		// Load
		search();

		/**
		 * Functions
		 */
		 function search() {
			Containers.search(vm.params)
						.then(function (containers) {
							vm.containers = containers;
							_reloadGrid();
						});
		 }
		 function startAllContainers() {
			 console.log('Start all containers');
			 Containers.start()
						.then(function (data) {
							console.log('Start all containers response', arguments);
							search();
						}, function (response) {
							console.log("Start all containers: Error with status code", response.status);
						});
		 }
		 function stopAllContainers() {
			 console.log('Stop all containers');
			 Containers.stop()
						.then(function (data) {
							console.log('Stop all containers response', arguments);
							search();
						}, function (response) {
							console.log("Stop all containers: Error with status code", response.status);
						});
		 }
		 function startContainer(cont) {
			 console.log('Start container ', cont);
			 Containers.byId(cont.Id)
			 			.start()
						.then(function (data) {
							console.log('Start container response', arguments);
							search();
						}, function (response) {
							console.log("Start container: Error with status code", response.status);
						});
		 }
		 function stopContainer(cont) {
			 console.log('Stop container', cont);
			 Containers.byId(cont.Id)
			 			.stop()
						.then(function (data) {
							console.log('Stop container response', arguments);
							search();
						}, function (response) {
							console.log("Stop container: Error with status code", response.status);
						});
		 }
 		 function isStoppable(cont) {
			 var status = $filter('cntStatus')(cont.Status);
			 return status.toLowerCase() == 'up';
		 }
  		 function isStartable(cont) {
			 var status = $filter('cntStatus')(cont.Status);
			 return status.toLowerCase() != 'up';
		 }

		 // Private functions
		 function _reloadGrid() {
			 vm.tableParams.reload();
		 }
	}
})();<commit_msg>Use promises to improve code and network usage<commit_after>(function () {
	angular
		.module('docker-manager-ui.containers')
		.controller('ContainersCtrl', ContainersCtrl);

	ContainersCtrl.$inject = ['$scope', '$filter', '$q', 'ngTableParams', 'Containers'];
	function ContainersCtrl (  $scope,   $filter,   $q,   NgTableParams,   Containers) {
		var vm = $scope;
		var _searching = undefined;

		/**
		 * Publish scope
		 */
		// Already loaded containers
		vm.containers = [];
		vm.params = {
			all: true,
			//limit: 100
		};

		// Table configuration
		vm.tableParams = new NgTableParams({
			page: 1,
			count: 2,
			sorting: {
				Image: 'asc'
			}
		}, {
			total: 0,
			getData: function ($defer, params) {
				_searching
					.then(function (data) {
						return _pageData(data, params);
					})
					.then($defer.resolve, $defer.reject);
			}
		});

		// Expose actions to views
		vm.search = search;
		vm.startAllContainers = startAllContainers;
		vm.stopAllContainers = stopAllContainers;
		vm.startContainer = startContainer;
		vm.stopContainer = stopContainer;
		vm.isStoppable = isStoppable;
		vm.isStartable = isStartable;

		// Load
		search();

		/**
		 * Functions
		 */
		 function search() {
			 console.log('Search containers');
			 _searching = Containers.search(vm.params)
									.then(_saveData)
									.then(_reloadGrid);
			return _searching;
		 }
		 function startAllContainers() {
			 console.log('Start all containers');
			 return Containers
			 			.start()
						.then(search, console.error);
		 }
		 function stopAllContainers() {
			 console.log('Stop all containers');
			 return Containers
			 			.stop()
						.then(search, console.error);
		 }
		 function startContainer(cont) {
			 console.log('Start container ', cont);
			 return Containers.byId(cont.Id)
			 			.start()
						.then(search, console.error);
		 }
		 function stopContainer(cont) {
			 console.log('Stop container', cont);
			 return Containers.byId(cont.Id)
			 			.stop()
						.then(search, console.error);
		 }
 		 function isStoppable(cont) {
			 var status = $filter('cntStatus')(cont.Status);
			 return status.toLowerCase() == 'up';
		 }
  		 function isStartable(cont) {
			 var status = $filter('cntStatus')(cont.Status);
			 return status.toLowerCase() != 'up';
		 }

		 // Private functions
		 function _pageData(data, tableParams) {
			 console.log('_pageData', data);
			// Update total count
			data = data || [];
			tableParams.total(data.length);

			// Sort
			var orderedData = tableParams.sorting() ?
				$filter('orderBy')(data, tableParams.orderBy()) :
				data;

			// Page
			if (orderedData.length > 0) {
				var start = (tableParams.page() - 1) * tableParams.count(),
					end = Math.min(orderedData.length, tableParams.page() * tableParams.count());
				orderedData = orderedData.slice(start, end);
			}

			return orderedData;
		 }

		 function _saveData(data) {
			 console.log('Storing search results. Total: ', data.length);
			 vm.containers = data;
			 return data;
		 }

		 function _reloadGrid(data) {
			 console.log('Reload grid with incomming data');
			 vm.tableParams.reload();
			 return data;
		 }

	}
})();<|endoftext|>


<commit_before>/**
 * CG Tecnico Invaders
 * CG45179 16'17
 *
 * @author: Rui Ventura ( ist181045 )
 * @author: Diogo Freitas ( ist181586 )
 * @author: Sara Azinhal ( ist181700 )
 */

import { Vector3 }  from '../lib/threejs/math/Vector3';

import Collidable from '../Collidable';

class Entity extends Collidable {

	constructor ( x, y, z ) {

		super( x, y, z );

		this.type = 'Entity';

		this.MAX_VELOCITY = 1000;

		this.updateBoundingBox = true;

		this.moving       = false;
		this.direction    = new Vector3();
		this.velocity     = new Vector3();
		this.acceleration = 300;
		this.friction     = 350;

	}

	setDirection ( x, y, z ) {

		this.direction.set( x, y, z ).normalize();

	}

	update ( dt ) {

		super.update();

		let updatePos = false;

		let v   = this.velocity.length();
		let dvf = this.friction * dt;

		if ( this.moving ) {

			updatePos = true;

			if ( v !== this.MAX_VELOCITY ) {

				let dv = this.acceleration * dt;

				if ( v + dv > this.MAX_VELOCITY ) {

					this.velocity.setLength( this.MAX_VELOCITY );

				} else if ( this.direction.dot( this.velocity ) < v ) {

					this.velocity.addScaledVector( this.direction, dvf );

				}

				this.velocity.addScaledVector( this.direction, dv );

			}

		} else if ( v > dvf ) {

			updatePos = true;

			if ( v !== this.direction.dot( this.velocity ) ) {

				this.direction.copy( this.velocity ).normalize();

			}

			this.velocity.addScaledVector( this.direction, -dvf );

		} else {

			this.velocity.setLength( 0 );

		}

		if ( updatePos ) {

			let ds = new Vector3().addScaledVector( this.velocity, dt );

			this.position.add( ds );
			this.boundingBox.translate( ds );
			this.boundingSphere.translate( ds );

		}

	}

}

export default Entity;
<commit_msg>Create var for dot product<commit_after>/**
 * CG Tecnico Invaders
 * CG45179 16'17
 *
 * @author: Rui Ventura ( ist181045 )
 * @author: Diogo Freitas ( ist181586 )
 * @author: Sara Azinhal ( ist181700 )
 */

import { Vector3 }  from '../lib/threejs/math/Vector3';

import Collidable from '../Collidable';

class Entity extends Collidable {

	constructor ( x, y, z ) {

		super( x, y, z );

		this.type = 'Entity';

		this.MAX_VELOCITY = 1000;

		this.updateBoundingBox = true;

		this.moving       = false;
		this.direction    = new Vector3();
		this.velocity     = new Vector3();
		this.acceleration = 300;
		this.friction     = 350;

	}

	setDirection ( x, y, z ) {

		this.direction.set( x, y, z ).normalize();

	}

	update ( dt ) {

		super.update();

		let updatePos = false;

		let v   = this.velocity.length();
		let dvf = this.friction * dt;

		let dot = this.direction.dot( this.velocity );

		if ( this.moving ) {

			updatePos = true;

			if ( v !== this.MAX_VELOCITY ) {

				let dv = this.acceleration * dt;

				if ( v + dv > this.MAX_VELOCITY ) {

					this.velocity.setLength( this.MAX_VELOCITY );

				} else if ( v !== dot ) {

					this.velocity.addScaledVector( this.direction, dvf );

				}

				this.velocity.addScaledVector( this.direction, dv );

			}

		} else if ( v > dvf ) {

			updatePos = true;

			if ( v !== dot ) {

				this.direction.copy( this.velocity ).normalize();

			}

			this.velocity.addScaledVector( this.direction, -dvf );

		} else {

			this.velocity.setLength( 0 );

		}

		if ( updatePos ) {

			let ds = new Vector3().addScaledVector( this.velocity, dt );

			this.position.add( ds );
			this.boundingBox.translate( ds );
			this.boundingSphere.translate( ds );

		}

	}

}

export default Entity;
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  var buildDir   = 'build';
  var releaseDir = 'release';

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
        compress: {
          drop_console: true
        },
        sourceMap: true,
      },
      build: {
        files: [{
          expand: true,
          cwd: 'scripts',
          src: ['**/*.js','!**/*.min.js'],
          ext: '.min.js',
          extDot: 'last',
          dest: buildDir+'/scripts'
        }]
      },
      merge: {
        files:  [{
          src: ['scripts/sdb*.js', 'scripts/custom*.js', 'scripts/lang*.js', '!scripts/*.min.js'],
          dest: buildDir+'/merged/scripts/sdb-all.min.js'
          //'build/merged/scripts/sdb-all.js': ['scripts/sdb*.js', 'scripts/custom.ext.js', 'scripts/langprovider.js']
        }]
      }

    },
    jshint: {
      options: {
        reporterOutput: buildDir+'/jshint-output.html',
        reporter: require('jshint-html-reporter'),
        force: true
      },
      all: ['Gruntfile.js','scripts/*.js']
    },
    cssmin: {
      options: {
        sourceMap: true,
      },
      build: {
        files: [{
          expand: true,
          cwd: 'styles',
          src: ['**/*.css','!**/*.min.css'],
          ext: '.min.css',
          extDot: 'last',
          dest: 'build/styles'
        }]
      },
      merge: {
        files: [{
          src: ['styles/*.css','!styles/*.min.css'],
          dest: buildDir+'/merged/styles/shelfdb-all.min.css'
        }]
      }
    },
    watch: {
      css: {
        files: ['styles/**/*.css', '!styles/**/*.min.css'],
        tasks: ['cssmin']
      },
      js: {
        files: ['scripts/**/*.js','!scripts/**/*.min.js'],
        tasks: ['uglify']
      }
    },
    clean: {
      all: [buildDir+'/*', releaseDir+'/*'],
      release: [releaseDir+'/*'],
      build: [buildDir+'/*']
    },
    copy: {
      release: {
        files: [
          {
            expand: true,
            src: ['img/**', 'lib/**', 'config/*.json', 'classes/**', 'pages/**', 'scripts/**', 'sql/**', 'styles/**', 'templates/**', '*.php', '!**/*.js', '!**/*.css'],
            dest: releaseDir+'/'
          }, {
            expand: true,
            cwd: buildDir+'/',
            src: '**',
            dest: releaseDir+'/'
          }
        ]
      },
      dev: {
        files: [
          {
            expand: true,
            src: ['lib/**', 'config/*.json', 'classes/**', 'pages/**', 'scripts/**', 'sql/**', 'templates/**', '*.php'],
            dest: releaseDir+'/'
          }
        ]
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-newer');

  // Default task(s).
  grunt.registerTask('all', ['newer:cssmin:build', 'newer:uglify:build', 'newer:jshint']);
  grunt.registerTask('rebuild_all', ['clean:build', 'all'])
  grunt.registerTask('merged', ['newer:cssmin:merge', 'newer:uglify:merge']);
  grunt.registerTask('release', ['all', 'newer:copy:release']);

};
<commit_msg>On release change debug to false<commit_after>module.exports = function(grunt) {

  var buildDir   = 'build';
  var releaseDir = 'release';

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
        compress: {
          drop_console: true
        },
        sourceMap: true,
      },
      build: {
        files: [{
          expand: true,
          cwd: 'scripts',
          src: ['**/*.js','!**/*.min.js'],
          ext: '.min.js',
          extDot: 'last',
          dest: buildDir+'/scripts'
        }]
      },
      merge: {
        files:  [{
          src: ['scripts/sdb*.js', 'scripts/custom*.js', 'scripts/lang*.js', '!scripts/*.min.js'],
          dest: buildDir+'/merged/scripts/sdb-all.min.js'
          //'build/merged/scripts/sdb-all.js': ['scripts/sdb*.js', 'scripts/custom.ext.js', 'scripts/langprovider.js']
        }]
      }

    },
    jshint: {
      options: {
        reporterOutput: buildDir+'/jshint-output.html',
        reporter: require('jshint-html-reporter'),
        force: true
      },
      all: ['Gruntfile.js','scripts/*.js']
    },
    cssmin: {
      options: {
        sourceMap: true,
      },
      build: {
        files: [{
          expand: true,
          cwd: 'styles',
          src: ['**/*.css','!**/*.min.css'],
          ext: '.min.css',
          extDot: 'last',
          dest: 'build/styles'
        }]
      },
      merge: {
        files: [{
          src: ['styles/*.css','!styles/*.min.css'],
          dest: buildDir+'/merged/styles/shelfdb-all.min.css'
        }]
      }
    },
    watch: {
      css: {
        files: ['styles/**/*.css', '!styles/**/*.min.css'],
        tasks: ['cssmin']
      },
      js: {
        files: ['scripts/**/*.js','!scripts/**/*.min.js'],
        tasks: ['uglify']
      }
    },
    clean: {
      all: [buildDir+'/*', releaseDir+'/*'],
      release: [releaseDir+'/*'],
      build: [buildDir+'/*']
    },
    copy: {
      release: {
        files: [
          {
            expand: true,
            src: ['img/**', 'lib/**', 'config/*.json', 'classes/**', 'pages/**', 'scripts/**', 'sql/**', 'styles/**', 'templates/**', '*.php', '!**/*.js', '!**/*.css'],
            dest: releaseDir+'/'
          }, {
            expand: true,
            cwd: buildDir+'/',
            src: '**',
            dest: releaseDir+'/'
          }
        ]
      },
      release_config: {
        src: 'config/config.json',
        dest: releaseDir+'/config/config.json',
        options: {
          process: function(content,srcPath) {
            var jsonObj = JSON.parse(content);
            // Change config contents for release
            jsonObj.config.debug = false;
            return JSON.stringify(jsonObj,null,4);
          }
        }
      },
      dev: {
        files: [
          {
            expand: true,
            src: ['lib/**', 'config/*.json', 'classes/**', 'pages/**', 'scripts/**', 'sql/**', 'templates/**', '*.php'],
            dest: releaseDir+'/'
          }
        ]
      },
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-newer');

  // Default task(s).
  grunt.registerTask('all', ['newer:cssmin:build', 'newer:uglify:build', 'newer:jshint']);
  grunt.registerTask('rebuild_all', ['clean:build', 'all'])
  grunt.registerTask('merged', ['newer:cssmin:merge', 'newer:uglify:merge']);
  grunt.registerTask('release', ['all', 'newer:copy:release', 'newer:copy:release_config']);

};
<|endoftext|>


<commit_before>/* eslint-disable max-len, no-var, func-names, space-before-function-paren, vars-on-top, no-plusplus, comma-dangle, no-return-assign, consistent-return, no-param-reassign, one-var, one-var-declaration-per-line, quotes, prefer-template, no-else-return, prefer-arrow-callback, no-unused-vars, no-underscore-dangle, no-shadow, no-mixed-operators, template-curly-spacing, camelcase, default-case, wrap-iife, semi, padded-blocks */
/* global notify */
/* global notifyPermissions */
/* global merge_request_widget */
/* global Turbolinks */

((global) => {
  var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>">

         <%= ci_success_icon %>

           Deployed to
           <a href="<%- url %>" target="_blank" class="environment">
             <%- name %>

           <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>">
             <%- deployed_at %>

           <a class="js-environment-link" href="<%- external_url %>" target="_blank">

             View on <%- external_url_formatted %>

          <a href="<%- stop_url %>" class="close-evn-link" data-method="post" rel="nofollow" data-confirm="Are you sure you want to stop this environment?">

            Stop environment

`;

  global.MergeRequestWidget = (function() {
    function MergeRequestWidget(opts) {
      // Initialize MergeRequestWidget behavior
      //
      //   check_enable           - Boolean, whether to check automerge status
      //   merge_check_url - String, URL to use to check automerge status
      //   ci_status_url        - String, URL to use to check CI status
      //
      this.opts = opts;
      this.$widgetBody = $('.mr-widget-body');
      $('#modal_merge_info').modal({
        show: false
      });
      this.clearEventListeners();
      this.addEventListeners();
      this.getCIStatus(false);
      this.retrieveSuccessIcon();

      this.ciStatusInterval = new global.SmartInterval({
        callback: this.getCIStatus.bind(this, true),
        startingInterval: 10000,
        maxInterval: 30000,
        hiddenInterval: 120000,
        incrementByFactorOf: 5000,
      });
      this.ciEnvironmentStatusInterval = new global.SmartInterval({
        callback: this.getCIEnvironmentsStatus.bind(this),
        startingInterval: 30000,
        maxInterval: 120000,
        hiddenInterval: 240000,
        incrementByFactorOf: 15000,
        immediateExecution: true,
      });
      notifyPermissions();
    }

    MergeRequestWidget.prototype.clearEventListeners = function() {
      return $(document).off('page:change.merge_request');
    };

    MergeRequestWidget.prototype.addEventListeners = function() {
      var allowedPages;
      allowedPages = ['show', 'commits', 'pipelines', 'changes'];
      $(document).on('page:change.merge_request', (function(_this) {
        return function() {
          var page;
          page = $('body').data('page').split(':').last();
          if (allowedPages.indexOf(page) < 0) {
            return _this.clearEventListeners();
          }
        };
      })(this));
    };

    MergeRequestWidget.prototype.retrieveSuccessIcon = function() {
      const $ciSuccessIcon = $('.js-success-icon');
      this.$ciSuccessIcon = $ciSuccessIcon.html();
      $ciSuccessIcon.remove();
    }

    MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) {
      if (deleteSourceBranch == null) {
        deleteSourceBranch = false;
      }
      return $.ajax({
        type: 'GET',
        url: $('.merge-request').data('url'),
        success: (function(_this) {
          return function(data) {
            var callback, urlSuffix;
            if (data.state === "merged") {
              urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : '';
              return window.location.href = window.location.pathname + urlSuffix;
            } else if (data.merge_error) {
              return _this.$widgetBody.html("
" + data.merge_error + "
");
            } else {
              callback = function() {
                return merge_request_widget.mergeInProgress(deleteSourceBranch);
              };
              return setTimeout(callback, 2000);
            }
          };
        })(this),
        dataType: 'json'
      });
    };

    MergeRequestWidget.prototype.cancelPolling = function () {
      this.ciStatusInterval.cancel();
      this.ciEnvironmentStatusInterval.cancel();
    };

    MergeRequestWidget.prototype.getMergeStatus = function() {
      return $.get(this.opts.merge_check_url, function(data) {
        return $('.mr-state-widget').replaceWith(data);
      });
    };

    MergeRequestWidget.prototype.ciLabelForStatus = function(status) {
      switch (status) {
        case 'success':
          return 'passed';
        case 'success_with_warnings':
          return 'passed with warnings';
        default:
          return status;
      }
    };

    MergeRequestWidget.prototype.getCIStatus = function(showNotification) {
      var _this;
      _this = this;
      $('.ci-widget-fetching').show();
      return $.getJSON(this.opts.ci_status_url, (function(_this) {
        return function(data) {
          var message, status, title;
          if (data.status === '') {
            return;
          }
          if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
          if (data.status !== _this.opts.ci_status && (data.status != null)) {
            _this.opts.ci_status = data.status;
            _this.showCIStatus(data.status);
            if (data.coverage) {
              _this.showCICoverage(data.coverage);
            }
            if (showNotification) {
              status = _this.ciLabelForStatus(data.status);
              if (status === "preparing") {
                title = _this.opts.ci_title.preparing;
                status = status.charAt(0).toUpperCase() + status.slice(1);
                message = _this.opts.ci_message.preparing.replace('{{status}}', status);
              } else {
                title = _this.opts.ci_title.normal;
                message = _this.opts.ci_message.normal.replace('{{status}}', status);
              }
              title = title.replace('{{status}}', status);
              message = message.replace('{{sha}}', data.sha);
              message = message.replace('{{title}}', data.title);
              notify(title, message, _this.opts.gitlab_icon, function() {
                this.close();
              });
            }
          }
        };
      })(this));
    };

    MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() {
      $.getJSON(this.opts.ci_environments_status_url, (environments) => {
        if (environments && environments.length) this.renderEnvironments(environments);
      });
    };

    MergeRequestWidget.prototype.renderEnvironments = function(environments) {
      for (let i = 0; i < environments.length; i++) {
        const environment = environments[i];
        if ($(`.mr-state-widget #${ environment.id }`).length) return;
        const $template = $(DEPLOYMENT_TEMPLATE);
        if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove();

        if (!environment.stop_url) {
          $('.js-stop-env-link', $template).remove();
        }

        if (environment.deployed_at && environment.deployed_at_formatted) {
          environment.deployed_at = gl.utils.getTimeago().format(environment.deployed_at, 'gl_en') + '.';
        } else {
          $('.js-environment-timeago', $template).remove();
          environment.name += '.';
        }
        environment.ci_success_icon = this.$ciSuccessIcon;
        const templateString = _.unescape($template[0].outerHTML);
        const template = _.template(templateString)(environment)
        this.$widgetBody.before(template);
      }
    };

    MergeRequestWidget.prototype.showCIStatus = function(state) {
      var allowed_states;
      if (state == null) {
        return;
      }
      $('.ci_widget').hide();
      allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"];
      if (indexOf.call(allowed_states, state) >= 0) {
        $('.ci_widget.ci-' + state).show();
        switch (state) {
          case "failed":
          case "canceled":
          case "not_found":
            return this.setMergeButtonClass('btn-danger');
          case "running":
            return this.setMergeButtonClass('btn-info');
          case "success":
          case "success_with_warnings":
            return this.setMergeButtonClass('btn-create');
        }
      } else {
        $('.ci_widget.ci-error').show();
        return this.setMergeButtonClass('btn-danger');
      }
    };

    MergeRequestWidget.prototype.showCICoverage = function(coverage) {
      var text;
      text = 'Coverage ' + coverage + '%';
      return $('.ci_widget:visible .ci-coverage').text(text);
    };

    MergeRequestWidget.prototype.setMergeButtonClass = function(css_class) {
      return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-info btn-create').addClass(css_class);
    };

    return MergeRequestWidget;

  })();

})(window.gl || (window.gl = {}));
<commit_msg>fix failing tests for merge_request_widget_spec.js<commit_after>/* eslint-disable max-len, no-var, func-names, space-before-function-paren, vars-on-top, no-plusplus, comma-dangle, no-return-assign, consistent-return, no-param-reassign, one-var, one-var-declaration-per-line, quotes, prefer-template, no-else-return, prefer-arrow-callback, no-unused-vars, no-underscore-dangle, no-shadow, no-mixed-operators, template-curly-spacing, camelcase, default-case, wrap-iife, semi, padded-blocks */
/* global notify */
/* global notifyPermissions */
/* global merge_request_widget */
/* global Turbolinks */

require('./smart_interval');

((global) => {
  var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>">

         <%= ci_success_icon %>

           Deployed to
           <a href="<%- url %>" target="_blank" class="environment">
             <%- name %>

           <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>">
             <%- deployed_at %>

           <a class="js-environment-link" href="<%- external_url %>" target="_blank">

             View on <%- external_url_formatted %>

          <a href="<%- stop_url %>" class="close-evn-link" data-method="post" rel="nofollow" data-confirm="Are you sure you want to stop this environment?">

            Stop environment

`;

  global.MergeRequestWidget = (function() {
    function MergeRequestWidget(opts) {
      // Initialize MergeRequestWidget behavior
      //
      //   check_enable           - Boolean, whether to check automerge status
      //   merge_check_url - String, URL to use to check automerge status
      //   ci_status_url        - String, URL to use to check CI status
      //
      this.opts = opts;
      this.$widgetBody = $('.mr-widget-body');
      $('#modal_merge_info').modal({
        show: false
      });
      this.clearEventListeners();
      this.addEventListeners();
      this.getCIStatus(false);
      this.retrieveSuccessIcon();

      this.ciStatusInterval = new global.SmartInterval({
        callback: this.getCIStatus.bind(this, true),
        startingInterval: 10000,
        maxInterval: 30000,
        hiddenInterval: 120000,
        incrementByFactorOf: 5000,
      });
      this.ciEnvironmentStatusInterval = new global.SmartInterval({
        callback: this.getCIEnvironmentsStatus.bind(this),
        startingInterval: 30000,
        maxInterval: 120000,
        hiddenInterval: 240000,
        incrementByFactorOf: 15000,
        immediateExecution: true,
      });
      notifyPermissions();
    }

    MergeRequestWidget.prototype.clearEventListeners = function() {
      return $(document).off('page:change.merge_request');
    };

    MergeRequestWidget.prototype.addEventListeners = function() {
      var allowedPages;
      allowedPages = ['show', 'commits', 'pipelines', 'changes'];
      $(document).on('page:change.merge_request', (function(_this) {
        return function() {
          var page;
          page = $('body').data('page').split(':').last();
          if (allowedPages.indexOf(page) < 0) {
            return _this.clearEventListeners();
          }
        };
      })(this));
    };

    MergeRequestWidget.prototype.retrieveSuccessIcon = function() {
      const $ciSuccessIcon = $('.js-success-icon');
      this.$ciSuccessIcon = $ciSuccessIcon.html();
      $ciSuccessIcon.remove();
    }

    MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) {
      if (deleteSourceBranch == null) {
        deleteSourceBranch = false;
      }
      return $.ajax({
        type: 'GET',
        url: $('.merge-request').data('url'),
        success: (function(_this) {
          return function(data) {
            var callback, urlSuffix;
            if (data.state === "merged") {
              urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : '';
              return window.location.href = window.location.pathname + urlSuffix;
            } else if (data.merge_error) {
              return _this.$widgetBody.html("
" + data.merge_error + "
");
            } else {
              callback = function() {
                return merge_request_widget.mergeInProgress(deleteSourceBranch);
              };
              return setTimeout(callback, 2000);
            }
          };
        })(this),
        dataType: 'json'
      });
    };

    MergeRequestWidget.prototype.cancelPolling = function () {
      this.ciStatusInterval.cancel();
      this.ciEnvironmentStatusInterval.cancel();
    };

    MergeRequestWidget.prototype.getMergeStatus = function() {
      return $.get(this.opts.merge_check_url, function(data) {
        return $('.mr-state-widget').replaceWith(data);
      });
    };

    MergeRequestWidget.prototype.ciLabelForStatus = function(status) {
      switch (status) {
        case 'success':
          return 'passed';
        case 'success_with_warnings':
          return 'passed with warnings';
        default:
          return status;
      }
    };

    MergeRequestWidget.prototype.getCIStatus = function(showNotification) {
      var _this;
      _this = this;
      $('.ci-widget-fetching').show();
      return $.getJSON(this.opts.ci_status_url, (function(_this) {
        return function(data) {
          var message, status, title;
          if (data.status === '') {
            return;
          }
          if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
          if (data.status !== _this.opts.ci_status && (data.status != null)) {
            _this.opts.ci_status = data.status;
            _this.showCIStatus(data.status);
            if (data.coverage) {
              _this.showCICoverage(data.coverage);
            }
            if (showNotification) {
              status = _this.ciLabelForStatus(data.status);
              if (status === "preparing") {
                title = _this.opts.ci_title.preparing;
                status = status.charAt(0).toUpperCase() + status.slice(1);
                message = _this.opts.ci_message.preparing.replace('{{status}}', status);
              } else {
                title = _this.opts.ci_title.normal;
                message = _this.opts.ci_message.normal.replace('{{status}}', status);
              }
              title = title.replace('{{status}}', status);
              message = message.replace('{{sha}}', data.sha);
              message = message.replace('{{title}}', data.title);
              notify(title, message, _this.opts.gitlab_icon, function() {
                this.close();
              });
            }
          }
        };
      })(this));
    };

    MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() {
      $.getJSON(this.opts.ci_environments_status_url, (environments) => {
        if (environments && environments.length) this.renderEnvironments(environments);
      });
    };

    MergeRequestWidget.prototype.renderEnvironments = function(environments) {
      for (let i = 0; i < environments.length; i++) {
        const environment = environments[i];
        if ($(`.mr-state-widget #${ environment.id }`).length) return;
        const $template = $(DEPLOYMENT_TEMPLATE);
        if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove();

        if (!environment.stop_url) {
          $('.js-stop-env-link', $template).remove();
        }

        if (environment.deployed_at && environment.deployed_at_formatted) {
          environment.deployed_at = gl.utils.getTimeago().format(environment.deployed_at, 'gl_en') + '.';
        } else {
          $('.js-environment-timeago', $template).remove();
          environment.name += '.';
        }
        environment.ci_success_icon = this.$ciSuccessIcon;
        const templateString = _.unescape($template[0].outerHTML);
        const template = _.template(templateString)(environment)
        this.$widgetBody.before(template);
      }
    };

    MergeRequestWidget.prototype.showCIStatus = function(state) {
      var allowed_states;
      if (state == null) {
        return;
      }
      $('.ci_widget').hide();
      allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"];
      if (indexOf.call(allowed_states, state) >= 0) {
        $('.ci_widget.ci-' + state).show();
        switch (state) {
          case "failed":
          case "canceled":
          case "not_found":
            return this.setMergeButtonClass('btn-danger');
          case "running":
            return this.setMergeButtonClass('btn-info');
          case "success":
          case "success_with_warnings":
            return this.setMergeButtonClass('btn-create');
        }
      } else {
        $('.ci_widget.ci-error').show();
        return this.setMergeButtonClass('btn-danger');
      }
    };

    MergeRequestWidget.prototype.showCICoverage = function(coverage) {
      var text;
      text = 'Coverage ' + coverage + '%';
      return $('.ci_widget:visible .ci-coverage').text(text);
    };

    MergeRequestWidget.prototype.setMergeButtonClass = function(css_class) {
      return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-info btn-create').addClass(css_class);
    };

    return MergeRequestWidget;

  })();

})(window.gl || (window.gl = {}));
<|endoftext|>