<commit_before>/**
 * rowcol - a library for row-column data manipulation
 * @module rowcol
 * @author Samuel Rouse <samuel.rouse@gmail.com>
 * @license MIT http://opensource.org/licenses/MIT
 */

/*--------------------------------------------------------------------------*/
/*
 * Constants and basic settings
 * Structure and code from Lo-Dash 2.4.1 <http://lodash.com/>
 */

const version = '3.0.0';

/*--------------------------------------------------------------------------*/

/* Functions */
const { has, objFromIndex } = require('./util');
const RCProxy = require('./proxy');

function getIndexesWithFunction(array, filter) {
  const indexes = [];
  const len = array.length;
  let i;

  for (i = 0; i < len; i += 1) {
    if (filter(array[i], i)) {
      indexes.push(i);
    }
  }

  return indexes;
}

function getIndexesWithValue(array, filter) {
  const indexes = [];
  const len = array.length;
  let i;

  for (i = 0; i < len; i += 1) {
    if (array[i] === filter) {
      indexes.push(i);
    }
  }

  return indexes;
}

/**
 * Returns an array of indexes that match a filter string or function.
 * @param {Array} array Array of values to match
 * @param {Function|String} filter Function or String to match array values.
 * @returns {Array} Array of indexes that match the filter.
 */
function getIndexes(array, filter) {
  if (typeof filter === 'function') {
    return getIndexesWithFunction(array, filter);
  }
  return getIndexesWithValue(array, filter);
}

/**
 * Returns the elements of an array using a list of selected indexes.
 * @param {Array} array
 * @param {Array} indexes
 * @returns {Array}
 */
function getByIndexes(array, indexes) {
  let i;
  const len = indexes.length;
  const data = [];

  for (i = 0; i < len; i += 1) {
    data.push(array[indexes[i]]);
  }
  return data;
}

/**
 * Performs the rotation for an unlimited (regular) rotation
 * @param {Array} arr
 * @param {Object} result
 * @returns {Object}
 */
function arrayRotateUnlimited(arr, result) {
  return arr.reduce((res, obj, i) => Object.entries(obj).reduce((acc, [key, val]) => {
    if (acc[key] === undefined) {
      acc[key] = [];
    }
    acc[key][i] = val;
    return acc;
  }, res), result);
}

/**
 * Performs the rotation for a limited (partial) rotation
 * @param {Array} arr
 * @param {Object} result
 * @param {Array|boolean} limited
 * @returns {Object}
 */
function arrayRotateLimited(arr, result, limited) {
  // If this is limited to the list of keys, get the keys for limited rotate
  // One pass to eliminate any unusable keys and create missing arrays
  const objKeys = (Array.isArray(limited) ? limited : Object.keys(result)).filter((key) => {
    // Create arrays for missing keys
    if (undefined === result[key]) {
      result[key] = [];
      return true;
    }

    // Check if existing keys are arrays
    return Array.isArray(result[key]);
  });

  arr.forEach((obj, i) => objKeys.reduce((acc, att) => {
    acc[att][i] = obj[att];
    return acc;
  }, result));

  return result;
}

/**
 * Error checking (and throwing) for the arrayRotate method
 * @param {Array} arr
 * @param {Object} [result] Result object to use
 * @param {boolean} [limited] Only update keys on the result object; a limited rotation
 */
function arrayRotateErrors(arr, result, limited) {
  // Not an array? Send it back.
  if (!Array.isArray(arr)) {
    throw new TypeError('RC: Argument is not an array');
  }

  if (limited && (typeof result !== 'object' || result === undefined)) {
    throw new TypeError("RC: Must pass a result object when 'limited' is true");
  }
}

/**
 * Rotate an array of row-data into a column-data object
 * @param {Array} arr
 * @param {Object} [result] Result object to use
 * @param {boolean} [limited] Only update keys on the result object; a limited rotation
 * @returns {Object}
 */
function arrayRotate(arr, result, limited = false) {
  arrayRotateErrors(arr, result, limited);

  const data = result || {};

  // Explicit check: you could pass [0], limited could be falsy.
  if (limited) {
    return arrayRotateLimited(arr, data, limited);
  }

  return arrayRotateUnlimited(arr, data);
}

/**
 *
 * @param obj
 * @param field
 * @param filter
 * @returns {Array}
 */
function filterIndexes(obj, field, filter) {
  let indexes = [];

  if (has(obj, field)) {
    indexes = getIndexes(obj[field], filter);
  }

  return indexes;
}

/**
 * Filters all properties in a column-data object using an array of indexes.
 * @param {Object} obj
 * @param {Array} indexes
 * @returns {Object}
 */
function filterMerge(obj, indexes) {
  // Don't waste time if there are no indexes to merge.
  if (indexes === undefined || !indexes.length) {
    return {};
  }

  return Object.entries(obj).reduce((acc, [key, val]) => {
    acc[key] = getByIndexes(val, indexes);
    return acc;
  }, {});
}

/**
 * Filter a column-data object for a particular field.
 * @param {Object} obj
 * @param {String} field
 * @param {Function|String} filter
 * @returns {*}
 */
function objectFilter(obj, field, filter) {
  return filterMerge(obj, filterIndexes(obj, field, filter));
}

/**
 * Finds the longest length of any property in a column-data object.
 * @param {Object} obj
 * @returns {number}
 */
function objectLength(obj) {
  return Math.max(0, ...Object.values(obj).map(arr => arr.length));
}

/**
 * Error throwing for object rotate
 * @param {Object} obj
 * @param result
 */
function objectRotateErrors(obj, result) {
  // Not an array? Send it back.
  if (typeof obj !== 'object') {
    throw new TypeError('RC: Argument is not an object');
  }

  // If a result is passed and isn't an array, send it back.
  if (undefined !== result && !Array.isArray(result)) {
    throw new TypeError('RC: Result argument is not an array');
  }
}

/**
 * Rotates column-data to row-data and optionally adds it to an existing array.
 * @param {Object} obj
 * @param {Array} [result] Optional array init which we should place rotated data.
 * @param {Boolean} [clearUndef]
 * @returns {Array}
 */
function objectRotate(obj, result, clearUndef) {
  // Call out for errors
  objectRotateErrors(obj, result);

  // Don't replace parameters to avoid optimization issues.
  const output = result || [];

  // Get the existing result array length
  const resultOffset = output.length;

  const len = objectLength(obj);

  for (let i = 0; i < len; i += 1) {
    output[i + resultOffset] = objFromIndex(obj, i, clearUndef);
  }

  return output;
}

/**
 * A generic rotate function that accepts row or column data to rotate.
 * @param {Object|Array} obj
 * @param {...*} [args]
 * @returns {Array|Object}
 */
function rotate(obj, ...args) {
  // Generic, which directs to the appropriate array/object rotate
  if (typeof obj !== 'object') throw new TypeError('RC: rotate requires an object or an array');

  if (Array.isArray(obj)) {
    return arrayRotate(obj, ...args);
  }
  return objectRotate(obj, ...args);
}

/**
 * Increment over column-data like it was array data, making a "read-only" object for each index.
 * Does not prevent modification of values with complex data types (objects, arrays).
 * @param {Object} obj
 * @param {Function} fn
 */
function readEach(obj, fn) {
  const len = objectLength(obj);

  for (let i = 0; i < len; i += 1) {
    fn(objFromIndex(obj, i));
  }
}

/**
 * Create a proxy
 * @param obj
 * @param index
 * @param clearUndef
 */
function proxyFromIndex(obj, index, clearUndef) {
  return new RCProxy(obj, index, clearUndef);
}

/**
 * Increment over column-data like it was array data, making a proxy object for each index.
 * @param {Object} obj
 * @param {Function} fn
 */
function objEach(obj, fn) {
  const len = objectLength(obj);
  let i = 0;
  let prox;

  for (; i < len; i += 1) {
    prox = new RCProxy(obj, i);

    fn(prox, i);

    prox.finalize();
  }
}

/*--------------------------------------------------------------------------*/

const rowcol = {
  rotate,
  proxy: proxyFromIndex,
  array: {
    getIndexes,
    getByIndexes,
    rotate: arrayRotate,
  },
  object: {
    filter: objectFilter,
    filterIndexes,
    filterMerge,
    rotate: objectRotate,
    objFromIndex,
    proxy: proxyFromIndex,
    readEach,
    each: objEach,
    objLength: objectLength,
  },
  VERSION: version,
};

/*--------------------------------------------------------------------------*/

module.exports = rowcol;
<commit_msg>CodeClimate cleanup<commit_after>/**
 * rowcol - a library for row-column data manipulation
 * @module rowcol
 * @author Samuel Rouse <samuel.rouse@gmail.com>
 * @license MIT http://opensource.org/licenses/MIT
 */

/*--------------------------------------------------------------------------*/
/*
 * Constants and basic settings
 * Structure and code from Lo-Dash 2.4.1 <http://lodash.com/>
 */

const version = '3.0.0';

/*--------------------------------------------------------------------------*/

/* Functions */
const { has, objFromIndex } = require('./util');
const RCProxy = require('./proxy');

function getIndexesWithFunction(array, filter) {
  const indexes = [];
  const len = array.length;
  let i;

  for (i = 0; i < len; i += 1) {
    if (filter(array[i], i)) {
      indexes.push(i);
    }
  }

  return indexes;
}

function getIndexesWithValue(array, filter) {
  const indexes = [];
  const len = array.length;
  let i;

  for (i = 0; i < len; i += 1) {
    if (array[i] === filter) {
      indexes.push(i);
    }
  }

  return indexes;
}

/**
 * Returns an array of indexes that match a filter string or function.
 * @param {Array} array Array of values to match
 * @param {Function|String} filter Function or String to match array values.
 * @returns {Array} Array of indexes that match the filter.
 */
function getIndexes(array, filter) {
  if (typeof filter === 'function') {
    return getIndexesWithFunction(array, filter);
  }
  return getIndexesWithValue(array, filter);
}

/**
 * Returns the elements of an array using a list of selected indexes.
 * @param {Array} array
 * @param {Array} indexes
 * @returns {Array}
 */
function getByIndexes(array, indexes) {
  let i;
  const len = indexes.length;
  const data = [];

  for (i = 0; i < len; i += 1) {
    data.push(array[indexes[i]]);
  }
  return data;
}

/**
 * Performs the rotation for an unlimited (regular) rotation
 * @param {Array} arr
 * @param {Object} result
 * @returns {Object}
 */
function arrayRotateUnlimited(arr, result) {
  return arr.reduce((res, obj, i) => Object.entries(obj).reduce((acc, [key, val]) => {
    if (acc[key] === undefined) {
      acc[key] = [];
    }
    acc[key][i] = val;
    return acc;
  }, res), result);
}

/**
 * Performs the rotation for a limited (partial) rotation
 * @param {Array} arr
 * @param {Object} data
 * @param {Array|boolean} limited
 * @returns {Object}
 */
function arrayRotateLimited(arr, data, limited) {
  // We are intentionally modifying the input, so we reassign it.
  const result = data;
  // If this is limited to the list of keys, get the keys for limited rotate
  // One pass to eliminate any unusable keys and create missing arrays
  const objKeys = (Array.isArray(limited) ? limited : Object.keys(result)).filter((key) => {
    // Create arrays for missing keys
    if (undefined === result[key]) {
      result[key] = [];
      return true;
    }

    // Check if existing keys are arrays
    return Array.isArray(result[key]);
  });

  arr.forEach((obj, i) => objKeys.reduce((acc, att) => {
    acc[att][i] = obj[att];
    return acc;
  }, result));

  return result;
}

/**
 * Error checking (and throwing) for the arrayRotate method
 * @param {Array} arr
 * @param {Object} [result] Result object to use
 * @param {boolean} [limited] Only update keys on the result object; a limited rotation
 */
function arrayRotateErrors(arr, result, limited) {
  // Not an array? Send it back.
  if (!Array.isArray(arr)) {
    throw new TypeError('RC: Argument is not an array');
  }

  if (limited && (typeof result !== 'object' || result === undefined)) {
    throw new TypeError("RC: Must pass a result object when 'limited' is true");
  }
}

/**
 * Rotate an array of row-data into a column-data object
 * @param {Array} arr
 * @param {Object} [result] Result object to use
 * @param {boolean} [limited] Only update keys on the result object; a limited rotation
 * @returns {Object}
 */
function arrayRotate(arr, result, limited = false) {
  arrayRotateErrors(arr, result, limited);

  const data = result || {};

  // Explicit check: you could pass [0], limited could be falsy.
  if (limited) {
    return arrayRotateLimited(arr, data, limited);
  }

  return arrayRotateUnlimited(arr, data);
}

/**
 *
 * @param obj
 * @param field
 * @param filter
 * @returns {Array}
 */
function filterIndexes(obj, field, filter) {
  let indexes = [];

  if (has(obj, field)) {
    indexes = getIndexes(obj[field], filter);
  }

  return indexes;
}

/**
 * Filters all properties in a column-data object using an array of indexes.
 * @param {Object} obj
 * @param {Array} indexes
 * @returns {Object}
 */
function filterMerge(obj, indexes) {
  // Don't waste time if there are no indexes to merge.
  if (indexes === undefined || !indexes.length) {
    return {};
  }

  return Object.entries(obj).reduce((acc, [key, val]) => {
    acc[key] = getByIndexes(val, indexes);
    return acc;
  }, {});
}

/**
 * Filter a column-data object for a particular field.
 * @param {Object} obj
 * @param {String} field
 * @param {Function|String} filter
 * @returns {*}
 */
function objectFilter(obj, field, filter) {
  return filterMerge(obj, filterIndexes(obj, field, filter));
}

/**
 * Finds the longest length of any property in a column-data object.
 * @param {Object} obj
 * @returns {number}
 */
function objectLength(obj) {
  return Math.max(0, ...Object.values(obj).map(arr => arr.length));
}

/**
 * Error throwing for object rotate
 * @param {Object} obj
 * @param result
 */
function objectRotateErrors(obj, result) {
  // Not an array? Send it back.
  if (typeof obj !== 'object') {
    throw new TypeError('RC: Argument is not an object');
  }

  // If a result is passed and isn't an array, send it back.
  if (undefined !== result && !Array.isArray(result)) {
    throw new TypeError('RC: Result argument is not an array');
  }
}

/**
 * Rotates column-data to row-data and optionally adds it to an existing array.
 * @param {Object} obj
 * @param {Array} [result] Optional array init which we should place rotated data.
 * @param {Boolean} [clearUndef]
 * @returns {Array}
 */
function objectRotate(obj, result, clearUndef) {
  // Call out for errors
  objectRotateErrors(obj, result);

  // Don't replace parameters to avoid optimization issues.
  const output = result || [];

  // Get the existing result array length
  const resultOffset = output.length;

  const len = objectLength(obj);

  for (let i = 0; i < len; i += 1) {
    output[i + resultOffset] = objFromIndex(obj, i, clearUndef);
  }

  return output;
}

/**
 * A generic rotate function that accepts row or column data to rotate.
 * @param {Object|Array} obj
 * @param {...*} [args]
 * @returns {Array|Object}
 */
function rotate(obj, ...args) {
  // Generic, which directs to the appropriate array/object rotate
  if (typeof obj !== 'object') throw new TypeError('RC: rotate requires an object or an array');

  if (Array.isArray(obj)) {
    return arrayRotate(obj, ...args);
  }
  return objectRotate(obj, ...args);
}

/**
 * Increment over column-data like it was array data, making a "read-only" object for each index.
 * Does not prevent modification of values with complex data types (objects, arrays).
 * @param {Object} obj
 * @param {Function} fn
 */
function readEach(obj, fn) {
  const len = objectLength(obj);

  for (let i = 0; i < len; i += 1) {
    fn(objFromIndex(obj, i));
  }
}

/**
 * Create a proxy
 * @param obj
 * @param index
 * @param clearUndef
 */
function proxyFromIndex(obj, index, clearUndef) {
  return new RCProxy(obj, index, clearUndef);
}

/**
 * Increment over column-data like it was array data, making a proxy object for each index.
 * @param {Object} obj
 * @param {Function} fn
 */
function objEach(obj, fn) {
  const len = objectLength(obj);
  let i = 0;
  let prox;

  for (; i < len; i += 1) {
    prox = new RCProxy(obj, i);

    fn(prox, i);

    prox.finalize();
  }
}

/*--------------------------------------------------------------------------*/

const rowcol = {
  rotate,
  proxy: proxyFromIndex,
  array: {
    getIndexes,
    getByIndexes,
    rotate: arrayRotate,
  },
  object: {
    filter: objectFilter,
    filterIndexes,
    filterMerge,
    rotate: objectRotate,
    objFromIndex,
    proxy: proxyFromIndex,
    readEach,
    each: objEach,
    objLength: objectLength,
  },
  VERSION: version,
};

/*--------------------------------------------------------------------------*/

module.exports = rowcol;
<|endoftext|>


<commit_before>var usersBlocked = 0,
    usersFound = 0,
    usersAlreadyBlocked = 0,
    usersSkipped = 0,
    totalCount = 0,
    errors = 0;
var batchBlockCount = 5;
var scrollerInterval = false,
    finderInterval = false,
    blockerInterval = false;
var userQueue = new Queue();

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    if (request.blockChainStart) {
        if ($(".GridTimeline .ProfileCard").length > 0) {
            sendResponse({ack: true});
            startBlockChain();
        }
        else {
            sendResponse({error: true, error_description: 'Navigate to a twitter following or followers page.'});
        }
    }
});
$("#blockAllUsers").click(startBlockChain);
function startBlockChain() {
    var result = confirm("Are you sure you want to block all users on this page that you aren't following?");
    if (!result)
        return;
    showDialog();
    scrollerInterval = setInterval(function() {
        window.scroll(0, $(document).height());
        if ($(".GridTimeline-end.has-more-items").length==0) {
            clearInterval(scrollerInterval);
            scrollerInterval = false;
            doBlocking();
            totalCount = $(".ProfileCard").length;
            $("#blockchain-dialog .totalCount").text(totalCount);
        }
    },500);
    finderInterval = setInterval(function() {
        doBlocking();
        if (usersFound==totalCount && totalCount > 0) {
            clearInterval(finderInterval);
            finderInterval = false;
        }
    },1000);
    blockerInterval = setInterval(function() {
        for (var i=0;i<batchBlockCount;i++) {
            var user = userQueue.dequeue();
            if (typeof user !== "undefined") {
                $.ajax({
                    url: "https://twitter.com/i/user/block",
                    method: "POST",
                    dataType: 'json',
                    data: {
                        authenticity_token: $("#signout-form input.authenticity_token").val(),
                        block_user: true,
                        impression_id: "",
                        report_type: "",
                        screen_name: user.name,
                        user_id: user.id
                    }
                }).done(function(response) {
                    //console.log(response);
                }).fail(function(xhr, text, err) {
                    errors++;
                    $("#blockchain-dialog .errorCount").text(errors);
                    //console.log(xhr);
                }).always(function() {
                    usersBlocked++;
                    $("#blockchain-dialog .usersBlocked").text(usersBlocked);
                    if ((usersBlocked == totalCount || usersBlocked == usersFound) && totalCount > 0) {
                        clearInterval(blockerInterval);
                        blockerInterval = false;
                    }
                });
            }
        }
    },40);
}

function doBlocking() {
    $(".ProfileCard:not(.blockchain-added)").each(function(i,e) {
        $(e).addClass("blockchain-added");
        if ($(e).find('.user-actions.following').length > 0) {
            usersSkipped++;
            $("#blockchain-dialog .usersSkipped").text(usersSkipped);
            return true;
        }
        if ($(e).find('.user-actions.blocked').length > 0) {
            usersAlreadyBlocked++;
            $("#blockchain-dialog .usersAlreadyBlocked").text(usersAlreadyBlocked);
            return true;
        }
        usersFound++;
        $("#blockchain-dialog .usersFound").text(usersFound);
        userQueue.enqueue({
            name: $(e).data('screen-name'),
            id: $(e).data('user-id')
        });
    });
}

function showDialog() {
    $("body").append(
'
'+
	'

'+
	'

'+
	'
'+
		'
'+
			'
Twitter Block Chain
'+
		'
'+
		'
'+
            '
Found:
'+
            '
Skipped:
'+
            '
Already Blocked:
'+
            '
Blocked:
'+
            '
Total:
'+
            '
Errors:
'+
		'
'+
		'
'+
			'
'+
				'<button id="done" class="btn primary-btn report-tweet-next-button" type="button">Done</button>'+
			'
'+
		'
'+
	'
'+
	'<button type="button" class="modal-btn modal-close js-close" aria-controls="block-or-report-dialog-dialog">'+
		''+
			'Close'+
		''+
	'</button>'+
	'

'+
'
'
    );
    $("#blockchain-dialog").show().find("button").click(function() {
        clearInterval(blockerInterval);
        clearInterval(scrollerInterval);
        clearInterval(finderInterval);
        usersBlocked = 0;
        usersFound = 0;
        usersAlreadyBlocked = 0;
        usersSkipped = 0;
        totalCount = 0;
        errors = 0;
        $("#blockchain-dialog .usersFound").text(usersFound);
        $("#blockchain-dialog .usersSkipped").text(usersSkipped);
        $("#blockchain-dialog .usersAlreadyBlocked").text(usersAlreadyBlocked);
        $("#blockchain-dialog .usersBlocked").text(usersBlocked);
        $("#blockchain-dialog .totalCount").text(totalCount);
        $("#blockchain-dialog .errorCount").text(errors);
        $("#blockchain-dialog").hide();
    });
}<commit_msg>changed the way follower/following page is detected<commit_after>var usersBlocked = 0,
    usersFound = 0,
    usersAlreadyBlocked = 0,
    usersSkipped = 0,
    totalCount = 0,
    errors = 0;
var batchBlockCount = 5;
var scrollerInterval = false,
    finderInterval = false,
    blockerInterval = false;
var userQueue = new Queue();

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    if (request.blockChainStart) {
        if ($(".ProfileNav-item--followers.is-active, .ProfileNav-item--following.is-active").length > 0) {
            sendResponse({ack: true});
            startBlockChain();
        }
        else {
            sendResponse({error: true, error_description: 'Navigate to a twitter following or followers page.'});
        }
    }
});
$("#blockAllUsers").click(startBlockChain);
function startBlockChain() {
    var result = confirm("Are you sure you want to block all users on this page that you aren't following?");
    if (!result)
        return;
    showDialog();
    scrollerInterval = setInterval(function() {
        window.scroll(0, $(document).height());
        if ($(".GridTimeline-end.has-more-items").length==0) {
            clearInterval(scrollerInterval);
            scrollerInterval = false;
            doBlocking();
            totalCount = $(".ProfileCard").length;
            $("#blockchain-dialog .totalCount").text(totalCount);
        }
    },500);
    finderInterval = setInterval(function() {
        doBlocking();
        if (usersFound==totalCount && totalCount > 0) {
            clearInterval(finderInterval);
            finderInterval = false;
        }
    },1000);
    blockerInterval = setInterval(function() {
        for (var i=0;i<batchBlockCount;i++) {
            var user = userQueue.dequeue();
            if (typeof user !== "undefined") {
                $.ajax({
                    url: "https://twitter.com/i/user/block",
                    method: "POST",
                    dataType: 'json',
                    data: {
                        authenticity_token: $("#signout-form input.authenticity_token").val(),
                        block_user: true,
                        impression_id: "",
                        report_type: "",
                        screen_name: user.name,
                        user_id: user.id
                    }
                }).done(function(response) {
                    //console.log(response);
                }).fail(function(xhr, text, err) {
                    errors++;
                    $("#blockchain-dialog .errorCount").text(errors);
                    //console.log(xhr);
                }).always(function() {
                    usersBlocked++;
                    $("#blockchain-dialog .usersBlocked").text(usersBlocked);
                    if ((usersBlocked == totalCount || usersBlocked == usersFound) && totalCount > 0) {
                        clearInterval(blockerInterval);
                        blockerInterval = false;
                    }
                });
            }
        }
    },40);
}

function doBlocking() {
    $(".ProfileCard:not(.blockchain-added)").each(function(i,e) {
        $(e).addClass("blockchain-added");
        if ($(e).find('.user-actions.following').length > 0) {
            usersSkipped++;
            $("#blockchain-dialog .usersSkipped").text(usersSkipped);
            return true;
        }
        if ($(e).find('.user-actions.blocked').length > 0) {
            usersAlreadyBlocked++;
            $("#blockchain-dialog .usersAlreadyBlocked").text(usersAlreadyBlocked);
            return true;
        }
        usersFound++;
        $("#blockchain-dialog .usersFound").text(usersFound);
        userQueue.enqueue({
            name: $(e).data('screen-name'),
            id: $(e).data('user-id')
        });
    });
}

function showDialog() {
    $("body").append(
'
'+
	'

'+
	'

'+
	'
'+
		'
'+
			'
Twitter Block Chain
'+
		'
'+
		'
'+
            '
Found:
'+
            '
Skipped:
'+
            '
Already Blocked:
'+
            '
Blocked:
'+
            '
Total:
'+
            '
Errors:
'+
		'
'+
		'
'+
			'
'+
				'<button id="done" class="btn primary-btn report-tweet-next-button" type="button">Done</button>'+
			'
'+
		'
'+
	'
'+
	'<button type="button" class="modal-btn modal-close js-close" aria-controls="block-or-report-dialog-dialog">'+
		''+
			'Close'+
		''+
	'</button>'+
	'

'+
'
'
    );
    $("#blockchain-dialog").show().find("button").click(function() {
        clearInterval(blockerInterval);
        clearInterval(scrollerInterval);
        clearInterval(finderInterval);
        usersBlocked = 0;
        usersFound = 0;
        usersAlreadyBlocked = 0;
        usersSkipped = 0;
        totalCount = 0;
        errors = 0;
        $("#blockchain-dialog .usersFound").text(usersFound);
        $("#blockchain-dialog .usersSkipped").text(usersSkipped);
        $("#blockchain-dialog .usersAlreadyBlocked").text(usersAlreadyBlocked);
        $("#blockchain-dialog .usersBlocked").text(usersBlocked);
        $("#blockchain-dialog .totalCount").text(totalCount);
        $("#blockchain-dialog .errorCount").text(errors);
        $("#blockchain-dialog").hide();
    });
}<|endoftext|>


<commit_before>export function initialize(container, application) {
  application.inject('route', 'Messenger', 'service:messenger');
  application.inject('controller', 'Messenger', 'service:messenger');
}

export default {
  name: 'services',
  initialize: initialize
};
<commit_msg>Fix initializer arity http://emberjs.com/deprecations/v2.x/\#toc_id-ember-application-app-initializer-initialize-arguments<commit_after>export function initialize(application) {
  application.inject('route', 'Messenger', 'service:messenger');
  application.inject('controller', 'Messenger', 'service:messenger');
}

export default {
  name: 'services',
  initialize: initialize
};
<|endoftext|>


<commit_before>angular.module("matsi.controllers")
    .controller("FellowCtrl", ['$rootScope', '$scope', '$cookies', 'Fellow', '$http', '$stateParams', 'Mentor', 'MailService', '$mdDialog', '$mdToast', '$location', 'utils', '$timeout',
        function($rootScope, $scope, $cookies, Fellow, $http, $stateParams, Mentor, MailService, $mdDialog, $mdToast, $location, utils, $timeout) {
            $scope.smarterer = function() {
                var code = $stateParams.code;
                $scope.code = code;
            };
            if (window.location.toString().indexOf('fellows/?code=') > -1) {
                var code = window.location.search;
                code = code.substring(1, code.length);
                var param = {
                    code: code
                };

                $http.post('/smarterer/code/', param).success(function(res) {
                    console.log(res);
                    $scope.fellow.badges = res.badges;
                    console.log($scope.fellow);
                    console.log($scope.fellow.badges);
                    Fellow.update($scope.fellow);
                });
            };
            //Smarterer & plum Checkbox
            $scope.check = false;
            $scope.plumCheck = false;
            $scope.toggleCheck = function(val) {
                if (val === "smarterer") {
                    $scope.check = !$scope.check;
                    console.log('s1', $scope.check);
                    console.log('p1', $scope.plumCheck);
                } else {
                    $scope.plumCheck = !$scope.plumCheck;
                    console.log('s', $scope.check);
                    console.log('p', $scope.plumCheck);
                }

            };
            // plum api
            $scope.plumEmail;
            $scope.plum = function() {
                console.log('plum function called');
                console.log($scope.fellow.plumEmail);
                var param = {
                    email: $scope.fellow.plumEmail,
                    fname: $scope.fellow.firstName,
                    lname: $scope.fellow.lastName
                };
                $http.post('/plum/api/', param).success(function(res) {
                    console.log('plum from ctrl', res);
                    console.log(res.candidates[0].badges);
                    var data = {
                        uid: $scope.fellow.uid,
                        plumBadges: res.candidates[0].badges
                    };
                    Fellow.update(data);
                });
            };

            //Date picker
            $scope.today = function() {
                $scope.dt = new Date();
                var curr_date = $scope.dt.getDate();
                var curr_month = $scope.dt.getMonth();
                var curr_year = $scope.dt.getFullYear();
                $scope.dt = curr_year + curr_month + curr_date;
            };
            $scope.today();
            $scope.clear = function() {
                $scope.dt = null;
            };
            $scope.toggleMin = function() {
                $scope.minDate = $scope.minDate ? null : new Date();
            };
            $scope.toggleMin();
            $scope.open = function($event) {
                $event.preventDefault();
                $event.stopPropagation();
                $scope.opened = true;
                setTimeout(function() {
                    $scope.opened = false;
                }, 10);
            };
            $scope.dateOptions = {
                formatYear: 'yy',
                startingDay: 1
            };
            $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
            $scope.format = $scope.formats[2];

            $scope.all = function() {
                $scope.fellows = Fellow.all();
            };

            $scope.findOne = function() {
                var uid = $rootScope.currentUser ? ($stateParams.uid || $rootScope.currentUser.uid) : $stateParams.uid;
                $scope.fellow = Fellow.findOne(uid);
                this.showMessageBox = true;
            };
            $scope.delete = function(fellowId) {
                Fellow.delete(fellowId);
            };
            $scope.update = function() {
                if ($rootScope.currentUser.uid === $scope.fellow.uid || $rootScope.currentUser.isAdmin) {
                    Fellow.update($scope.fellow, function(err) {
                        if (err !== null) {
                            $mdDialog.show(
                                $mdDialog.alert()
                                .title('Update error')
                                .content('An error occured,  try again later')
                                .ariaLabel('Password notification')
                                .ok('Okay!')

                            );
                        }

                        if ($scope.plumCheck) {
                            console.log('plum is checked');
                            $scope.plum();
                        }
                        if ($scope.check) {
                            window.location.assign('https://smarterer.com/oauth/authorize?client_id=b30a2803ffe34bc68a6fe7757b039468&callback_url=http%3A%2F%2Fmatsi.herokuapp.com%2Ffellows%2F');
                        } else {
                            $location.path('fellows/' + $rootScope.currentUser.uid);
                        }

                    });
                }
            };
            $scope.showBox = function() {
                $scope.showMessageBox = false;
            };
            $scope.mentorConstraints = function(ev) {
                Fellow.mentorConstraint($stateParams.uid, function(res, hasUnmentored) {
                    if (res) {
                        if (hasUnmentored) {
                            $scope.sendRequest();
                        } else {
                            utils.showAlert(ev, 'This fellow is already being mentored, please select a fellow that is not currently being mentored');
                        }
                    } else {
                        $scope.sendRequest();
                    }
                });
            };
            $scope.sendRequest = function() {
                $scope.fellow.reason = $scope.fellow.message;
                MailService.send(1, $scope.fellow);
                Fellow.request($scope.fellow);
            };
        }
    ]);
<commit_msg>another attempt tp fix smarterer bug<commit_after>angular.module("matsi.controllers")
    .controller("FellowCtrl", ['$rootScope', '$scope', '$cookies', 'Fellow', '$http', '$stateParams', 'Mentor', 'MailService', '$mdDialog', '$mdToast', '$location', 'utils', '$timeout',
        function($rootScope, $scope, $cookies, Fellow, $http, $stateParams, Mentor, MailService, $mdDialog, $mdToast, $location, utils, $timeout) {
            $scope.smarterer = function() {
                var code = $stateParams.code;
                $scope.code = code;
            };
            if (window.location.toString().indexOf('fellows/?code=') > -1) {
                var code = window.location.search;
                code = code.substring(1, code.length);
                var param = {
                    code: code
                };

                $http.post('/smarterer/code/', param).success(function(res) {
                    console.log(res);
                    var data = {
                        uid: $scope.fellow.uid,
                        badges: res.badges
                    };
                    console.log(data);
                    Fellow.update(data);
                });
            };
            //Smarterer & plum Checkbox
            $scope.check = false;
            $scope.plumCheck = false;
            $scope.toggleCheck = function(val) {
                if (val === "smarterer") {
                    $scope.check = !$scope.check;
                    console.log('s1', $scope.check);
                    console.log('p1', $scope.plumCheck);
                } else {
                    $scope.plumCheck = !$scope.plumCheck;
                    console.log('s', $scope.check);
                    console.log('p', $scope.plumCheck);
                }

            };
            // plum api
            $scope.plumEmail;
            $scope.plum = function() {
                console.log('plum function called');
                console.log($scope.fellow.plumEmail);
                var param = {
                    email: $scope.fellow.plumEmail,
                    fname: $scope.fellow.firstName,
                    lname: $scope.fellow.lastName
                };
                $http.post('/plum/api/', param).success(function(res) {
                    console.log('plum from ctrl', res);
                    console.log(res.candidates[0].badges);
                    var data = {
                        uid: $scope.fellow.uid,
                        plumBadges: res.candidates[0].badges
                    };
                    Fellow.update(data);
                });
            };

            //Date picker
            $scope.today = function() {
                $scope.dt = new Date();
                var curr_date = $scope.dt.getDate();
                var curr_month = $scope.dt.getMonth();
                var curr_year = $scope.dt.getFullYear();
                $scope.dt = curr_year + curr_month + curr_date;
            };
            $scope.today();
            $scope.clear = function() {
                $scope.dt = null;
            };
            $scope.toggleMin = function() {
                $scope.minDate = $scope.minDate ? null : new Date();
            };
            $scope.toggleMin();
            $scope.open = function($event) {
                $event.preventDefault();
                $event.stopPropagation();
                $scope.opened = true;
                setTimeout(function() {
                    $scope.opened = false;
                }, 10);
            };
            $scope.dateOptions = {
                formatYear: 'yy',
                startingDay: 1
            };
            $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
            $scope.format = $scope.formats[2];

            $scope.all = function() {
                $scope.fellows = Fellow.all();
            };

            $scope.findOne = function() {
                var uid = $rootScope.currentUser ? ($stateParams.uid || $rootScope.currentUser.uid) : $stateParams.uid;
                $scope.fellow = Fellow.findOne(uid);
                this.showMessageBox = true;
            };
            $scope.delete = function(fellowId) {
                Fellow.delete(fellowId);
            };
            $scope.update = function() {
                if ($rootScope.currentUser.uid === $scope.fellow.uid || $rootScope.currentUser.isAdmin) {
                    Fellow.update($scope.fellow, function(err) {
                        if (err !== null) {
                            $mdDialog.show(
                                $mdDialog.alert()
                                .title('Update error')
                                .content('An error occured,  try again later')
                                .ariaLabel('Password notification')
                                .ok('Okay!')

                            );
                        }

                        if ($scope.plumCheck) {
                            console.log('plum is checked');
                            $scope.plum();
                        }
                        if ($scope.check) {
                            window.location.assign('https://smarterer.com/oauth/authorize?client_id=b30a2803ffe34bc68a6fe7757b039468&callback_url=http%3A%2F%2Fmatsi.herokuapp.com%2Ffellows%2F');
                        } else {
                            $location.path('fellows/' + $rootScope.currentUser.uid);
                        }

                    });
                }
            };
            $scope.showBox = function() {
                $scope.showMessageBox = false;
            };
            $scope.mentorConstraints = function(ev) {
                Fellow.mentorConstraint($stateParams.uid, function(res, hasUnmentored) {
                    if (res) {
                        if (hasUnmentored) {
                            $scope.sendRequest();
                        } else {
                            utils.showAlert(ev, 'This fellow is already being mentored, please select a fellow that is not currently being mentored');
                        }
                    } else {
                        $scope.sendRequest();
                    }
                });
            };
            $scope.sendRequest = function() {
                $scope.fellow.reason = $scope.fellow.message;
                MailService.send(1, $scope.fellow);
                Fellow.request($scope.fellow);
            };
        }
    ]);
<|endoftext|>


<commit_before>var jobRunsController = angular.module('geneHive.JobRunsController', []);

jobRunsController.controller('JobRunsCtrl', ['JobRun', '$scope','$http','$sortService','GridService',
  function(JobRun,$scope,$http,$sortService,GridService) {
    $scope.selectedJobRuns = [];
    $scope.isCollapsed = true;
    // default to the listing view
    $scope.subview = 'list';

    $scope.getInclude = function(){
      if ($scope.subview == 'list'){
          return 'partials/jobRuns.html'
      }else{
        return 'partials/jobRunDetails.html'
      }
    }
    $scope.showJobRuns = function(){
      $scope.subview ='list';
    }
    $scope.filterOptions = {
      filterText: ''
    };

    var showJobRun = function(jobRun){

      // Creation Date
      // Start Date
      // Stop Date
      // Input Files
      // Input Params
      // Output Files
      // STD out
      // STE err
      // Images
      var jrun = {};
      jrun.id = jobRun.id;
      jrun.creationDate = jobRun.creationDatetime;
      jrun.startDate = jobRun.runDatetime;
      jrun.stopDate = jobRun.stopDatetime;
      jrun.inputFiles = [];
      jrun.inputParams = [];
      jrun.outputImages = [];
      jrun.outputFiles = [];
      angular.forEach(jobRun.inputTypes,function(val,key){
        var jobParamName = key;
        var jobParamValue = jobRun.inputs[key];
        if(val.type == 'file'){
          // if its a file, append:
          //the file type
          //the sys ID of the file
          jrun.inputFiles.push({'inputParamName':jobParamName,'fileType':val.fileType,'systemID':jobParamValue});
        }
        jrun.inputParams.push({'inputParamName':jobParamName,'inputParamValue':jobParamValue,'inputParamType':val.type});

      })// end input types

      angular.forEach(jobRun.outputTypes,function(val,key){
        var outputName = key;
        var outputValue = jobRun.outputs[key]
        // they should all be files but lets check
        if(val.type == 'file'){
          if(val.fileType == 'JPG'){
            var url = 'www.something' + jobRun.outputs[key]
            jrun.outputImages.push({'outfileURL':url})
          }
          var token = jobRun.outputTokens[outputName]
          var downloadLink = '/GeneHive/api/v2/WorkFileContents/' + outputValue[0] + "/" + outputName + "?token" + token
          jrun.outputFiles.push({'systemID':outputValue,'fileType':val.fileType,'outputName':outputName,'token':token,'link':downloadLink})
        }
      })// end output types
      jrun.consoleOutput = jobRun.consoleOutput;
      jrun.consoleError = jobRun.consoleError;
      jrun.trashed = jobRun.trashed;
      jrun.children = jobRun.children;
      $scope.jrun = jrun;
    }

    var dateSort=function(x,y) {
	   var dx=Date.parse(x)
	   var dy=Date.parse(y)
	   if(dx<dy) return -1;
	   if(dy<dx) return 1;
	   return 0;
    };
    var columnDefs=[
      {field:'id',displayName:'Details',cellTemplate:'
view
 '},
	    {field:'id', displayName:'ID',width: 60},
      {field:"inputs.name[0]", displayName:'Name'},
      {field:'creator', displayName:'Creator'},
      {field:'jobType', displayName:'Job Type'},
      {field:'executionLocation', displayName:'Execution Location'},
      {field:'runDatetime',displayName:'Run Date', sortFn: dateSort },
      {field:'status',displayName:'Status',cellTemplate: '

{{row.getProperty(col.field)}}

'}

    ];
    GridService.initGrid($scope, $sortService, JobRun, $scope.selectedJobRuns, columnDefs);

    $scope.$watch('selectedJobRuns', function(newValue, oldValue){
    // only make the call if selectedJobRuns has a length of at least 1
    if ($scope.selectedJobRuns.length ) {
        showJobRun(newValue[0])
    }
    },true);
    $scope.showJobRunDetails = function(jobRunId){
      // its kinda gross to depend on this
      var jobRuns = $scope.cachedServerData.filter(
        function(jr){
          return (jr.id === jobRunId)
        }
      )
      $scope.subview = 'detail';
      showJobRun(jobRuns[0]);
    }

}]);<commit_msg>displaying job run images and colors for job run status<commit_after>var jobRunsController = angular.module('geneHive.JobRunsController', []);

jobRunsController.controller('JobRunsCtrl', ['JobRun', '$scope','$http','$sortService','GridService',
  function(JobRun,$scope,$http,$sortService,GridService) {
    $scope.selectedJobRuns = [];
    $scope.isCollapsed = true;
    // default to the listing view
    $scope.subview = 'list';

    $scope.getInclude = function(){
      if ($scope.subview == 'list'){
          return 'partials/jobRuns.html'
      }else{
        return 'partials/jobRunDetails.html'
      }
    }
    $scope.showJobRuns = function(){
      $scope.subview ='list';
    }
    $scope.filterOptions = {
      filterText: ''
    };

    var showJobRun = function(jobRun){

      // Creation Date
      // Start Date
      // Stop Date
      // Input Files
      // Input Params
      // Output Files
      // STD out
      // STE err
      // Images
      var jrun = {};
      jrun.id = jobRun.id;
      jrun.creationDate = jobRun.creationDatetime;
      jrun.startDate = jobRun.runDatetime;
      jrun.stopDate = jobRun.stopDatetime;
      jrun.inputFiles = [];
      jrun.inputParams = [];
      jrun.outputImages = [];
      jrun.outputFiles = [];
      angular.forEach(jobRun.inputTypes,function(val,key){
        var jobParamName = key;
        var jobParamValue = jobRun.inputs[key];
        if(val.type == 'file'){
          // if its a file, append:
          //the file type
          //the sys ID of the file
          jrun.inputFiles.push({'inputParamName':jobParamName,'fileType':val.fileType,'systemID':jobParamValue});
        }
        jrun.inputParams.push({'inputParamName':jobParamName,'inputParamValue':jobParamValue,'inputParamType':val.type});

      })// end input types

      angular.forEach(jobRun.outputTypes,function(val,key){
        var outputName = key;
        var outputValue = jobRun.outputs[key]
        var token = jobRun.outputTokens[outputName]
        // they should all be files but lets check
        if(val.type == 'file'){
          jrun.fileSize = bytesToSize(outputValue.length)
          if(val.fileType == 'JPG'){
            var url = '/GeneHive/api/v2/WorkFileContents/' + outputValue[0] + "/" + outputName + "?token" + token
            jrun.outputImages.push({'outfileURL':url})
          }
          var downloadLink = '/GeneHive/api/v2/WorkFileContents/' + outputValue[0] + "/" + outputName + "?token" + token
          jrun.outputFiles.push({'systemID':outputValue,'fileType':val.fileType,'outputName':outputName,'token':token,'link':downloadLink})
        }
      })// end output types
      jrun.consoleOutput = jobRun.consoleOutput;
      jrun.consoleError = jobRun.consoleError;
      jrun.trashed = jobRun.trashed;
      jrun.children = jobRun.children;
      $scope.jrun = jrun;
    }

    var dateSort=function(x,y) {
	   var dx=Date.parse(x)
	   var dy=Date.parse(y)
	   if(dx<dy) return -1;
	   if(dy<dx) return 1;
	   return 0;
    };
    var columnDefs=[
      {field:'id',displayName:'Details',cellTemplate:'
view
 '},
	    {field:'id', displayName:'ID',width: 60},
      {field:"inputs.name[0]", displayName:'Name'},
      {field:'creator', displayName:'Creator'},
      {field:'jobType', displayName:'Job Type'},
      {field:'executionLocation', displayName:'Execution Location'},
      {field:'runDatetime',displayName:'Run Date', sortFn: dateSort },
      {field:'status',displayName:'Status',cellTemplate: '

{{row.getProperty(col.field)}}

'}

    ];
    GridService.initGrid($scope, $sortService, JobRun, $scope.selectedJobRuns, columnDefs);

    $scope.$watch('selectedJobRuns', function(newValue, oldValue){
    // only make the call if selectedJobRuns has a length of at least 1
    if ($scope.selectedJobRuns.length ) {
        showJobRun(newValue[0])
    }
    },true);
    $scope.showJobRunDetails = function(jobRunId){
      // its kinda gross to depend on this
      var jobRuns = $scope.cachedServerData.filter(
        function(jr){
          return (jr.id === jobRunId)
        }
      )
      $scope.subview = 'detail';
      showJobRun(jobRuns[0]);
    }

}]);<|endoftext|>


<commit_before>import * as types from './types'
import log4js from 'log4js'
import { randomBytes, createHash } from 'crypto'

const API_URL = 'https://app-co-api.herokuapp.com'

const logger = log4js.getLogger(__filename)

const updateAppList = (apps, version) => {
  const lastUpdated = Date.now()
  return {
    type: types.UPDATE_APP_LIST,
    payload: {
      apps,
      version,
      lastUpdated
    }
  }
}

const updateInstanceIdentifier = instanceIdentifier => {
  const instanceCreationDate = Date.now()
  return {
    type: types.UPDATE_INSTANCE_IDENTIFIER,
    payload: {
      instanceIdentifier,
      instanceCreationDate
    }
  }
}

const refreshAppList = (
  browserApiUrl,
  instanceIdentifier,
  instanceCreationDate
) => {
  return dispatch => {
    logger.info('refreshAppList')
    if (instanceIdentifier) {
      return fetch(
        `${browserApiUrl}/data?id=${instanceIdentifier}&created=${instanceCreationDate}`
      )
        .then(response => response.text())
        .then(responseText => JSON.parse(responseText))
        .then(responseJson => {
          dispatch(updateAppList(responseJson.apps, responseJson.version))
        })
        .catch(error => {
          logger.error('refreshAppList:', error)
        })
    } else {
      return null
    }
  }
}

const generateInstanceIdentifier = () => {
  logger.info('Generating new instance identifier')
  return dispatch => {
    const instanceIdentifier = createHash('sha256')
      .update(randomBytes(256))
      .digest('hex')
    dispatch(updateInstanceIdentifier(instanceIdentifier))
  }
}

const doFetchApps = () => async dispatch => {
  dispatch({
    type: types.FETCH_APPS_STARTED
  })
  try {
    const res = await fetch(`${API_URL}/api/app-mining-apps`)

    const allBlockstackApps = await res.json()

    const apps = allBlockstackApps.apps.filter(
      app => app.category !== 'Sample Blockstack Apps'
    )

    const categories = [...new Set(apps.map(app => app.category))]

    const appsByCategory = categories.map(category => ({
      label: category,
      apps: apps.filter(app => app.category === category)
    }))

    const topApps = allBlockstackApps.apps.filter(app => app.miningReady)

    dispatch({
      type: types.FETCH_APPS_FINISHED,
      payload: {
        apps,
        topApps,
        appsByCategory
      }
    })
  } catch (e) {
    dispatch({
      type: types.FETCH_APPS_ERROR,
      payload: {
        error: e.msg
      }
    })
  }
}

const AppsActions = {
  updateAppList,
  refreshAppList,
  generateInstanceIdentifier,
  doFetchApps
}

export default AppsActions
<commit_msg>update app.co api url<commit_after>import * as types from './types'
import log4js from 'log4js'
import { randomBytes, createHash } from 'crypto'

const API_URL = 'https://api.app.co'

const logger = log4js.getLogger(__filename)

const updateAppList = (apps, version) => {
  const lastUpdated = Date.now()
  return {
    type: types.UPDATE_APP_LIST,
    payload: {
      apps,
      version,
      lastUpdated
    }
  }
}

const updateInstanceIdentifier = instanceIdentifier => {
  const instanceCreationDate = Date.now()
  return {
    type: types.UPDATE_INSTANCE_IDENTIFIER,
    payload: {
      instanceIdentifier,
      instanceCreationDate
    }
  }
}

const refreshAppList = (
  browserApiUrl,
  instanceIdentifier,
  instanceCreationDate
) => dispatch => {
    logger.info('refreshAppList')
    if (instanceIdentifier) {
      return fetch(
        `${browserApiUrl}/data?id=${instanceIdentifier}&created=${instanceCreationDate}`
      )
        .then(response => response.text())
        .then(responseText => JSON.parse(responseText))
        .then(responseJson => {
          dispatch(updateAppList(responseJson.apps, responseJson.version))
        })
        .catch(error => {
          logger.error('refreshAppList:', error)
        })
    } else {
      return null
    }
  }

const generateInstanceIdentifier = () => {
  logger.info('Generating new instance identifier')
  return dispatch => {
    const instanceIdentifier = createHash('sha256')
      .update(randomBytes(256))
      .digest('hex')
    dispatch(updateInstanceIdentifier(instanceIdentifier))
  }
}

const doFetchApps = () => async dispatch => {
  dispatch({
    type: types.FETCH_APPS_STARTED
  })
  try {
    const res = await fetch(`${API_URL}/api/app-mining-apps`)

    const allBlockstackApps = await res.json()

    const apps = allBlockstackApps.apps.filter(
      app => app.category !== 'Sample Blockstack Apps'
    )

    const categories = [...new Set(apps.map(app => app.category))]

    const appsByCategory = categories.map(category => ({
      label: category,
      apps: apps.filter(app => app.category === category)
    }))

    const topApps = allBlockstackApps.apps.filter(app => app.miningReady)

    dispatch({
      type: types.FETCH_APPS_FINISHED,
      payload: {
        apps,
        topApps,
        appsByCategory
      }
    })
  } catch (e) {
    dispatch({
      type: types.FETCH_APPS_ERROR,
      payload: {
        error: e.msg
      }
    })
  }
}

const AppsActions = {
  updateAppList,
  refreshAppList,
  generateInstanceIdentifier,
  doFetchApps
}

export default AppsActions
<|endoftext|>


<commit_before>define([
  'underscore',
  'backbone',
  'models/memento'
], function( _, Backbone, Memento ) {
  'use strict';

  // Utility functions.

  /**
   * Converts an object to an array.
   * Is the identity function if an array is passed in.
   */
  function toArray( object ) {
    return _.isArray( object ) ? object : [ object ];
  }

  /**
   * If the array is of length one, just return that element.
   * Is the identity function otherwise.
   */
  function extractSingleton( array ) {
    return array.length === 1 ? array[0] : array;
  }

  function EditorHistory() {
    this.current = null;

    this.undoStack = [];
    this.redoStack = [];

    // Store a state to determine whether we've changed a model/collection.
    this.previousState = null;
  }

  /**
   * There are four types of history states:
   * - A Backbone.Model.
   * - A Backbone.Collection.
   * - An array of Backbone.Models.
   * - An array of Backbone.Collections.
   */
  EditorHistory.prototype = {
    /**
     * Save the target's attributes.
     * Wipes the redo stack.
     */
    save: function( target ) {
      if ( this.current ) {
        this.undoStack.push( this.current );
      }

      this.current = this.snapshot( target );
      this.redoStack = [];
    },

    /**
     * Take a snapshot of the current state of the target.
     * Returns an array of mementos if target is an array.
     * Returns a single memento otherwise.
     */
    snapshot: function( target ) {
      if ( _.isArray( target ) ) {
        var mementos = target.map(function( element ) {
          return new Memento( element );
        });

        return extractSingleton( mementos );
      }

      return new Memento( target );
    },

    /**
     * Begin tracking a target.
     */
    begin: function( target ) {
      // Can't track nothing.
      if ( _.isEmpty( target ) ) {
        return;
      }

      this.previousState = this.snapshot( target );
      // Save if we don't have a baseline history.
      if ( !this.undoStack.length ) {
        this.save( target );
      }
    },

    /**
     * Stop tracking a target and push changes to history if anything changed.
     */
    end: function() {
      if ( !this.previousState ) {
        return;
      }

      var targets = toArray( this.previousState ).filter(function( memento ) {
        return !_.isEqual( memento.state, memento.target.toJSON() );
      }).map(function( memento ) {
        return memento.target;
      });

      // Save only if we have anything to save.
      if ( targets.length ) {
        // Don't save it as an array if there's only one object.
        this.save( extractSingleton( targets ) );
      }
    },

    /**
     * Time travel towards the forwardStack and away from the backwardStack.
     */
    timeTravel: function( forwardStack, backwardStack ) {
      // Don't do anything if we can't time travel further.
      if ( !forwardStack.length ) {
        return;
      }

      if ( this.current ) {
        backwardStack.push( this.current );
      }

      this.current = forwardStack.pop();

      var that = this;
      toArray( this.current ).forEach(function( memento ) {
        memento.restore();

        // Restore model references in mementos.
        if ( memento.target instanceof Backbone.Collection ) {
          that.reference( memento.target );
        }
      });

      return this;
    },

    undo: function() { return this.timeTravel( this.undoStack, this.redoStack ); },
    redo: function() { return this.timeTravel( this.redoStack, this.undoStack ); },

    clear: function() {
      this.undoStack = [];
      this.redoStack = [];
    },

    /**
     * Goes through the undo and redo stacks and rebuilds references to models.
     */
    reference: function( collection ) {
      this.undoStack.concat( this.redoStack ).forEach(function( state ) {
        toArray( state ).forEach(function( memento ) {
          memento.reference( collection );
        });
      });
    }
  };

  return EditorHistory;
});
<commit_msg>Remove need for utility functions in EditorHistory by storing all states as arrays of Mementos.<commit_after>define([
  'underscore',
  'backbone',
  'models/memento'
], function( _, Backbone, Memento ) {
  'use strict';

  /**
   * A state is an array of Mementos.
   */
  function EditorHistory() {
    this.current = null;

    this.undoStack = [];
    this.redoStack = [];

    // Store a state to determine whether we've changed a model/collection.
    this.previousState = null;
  }

  /**
   * There are four types of history states:
   * - A Backbone.Model.
   * - A Backbone.Collection.
   * - An array of Backbone.Models.
   * - An array of Backbone.Collections.
   *
   * These states are all stored as an array of Mementos.
   */
  EditorHistory.prototype = {
    /**
     * Save the target's attributes.
     * Wipes the redo stack.
     */
    save: function( target ) {
      if ( this.current ) {
        this.undoStack.push( this.current );
      }

      this.current = this.snapshot( target );
      this.redoStack = [];
    },

    /**
     * Take a snapshot of the current state of the target.
     * Returns an array of mementos.
     */
    snapshot: function( target ) {
      if ( _.isArray( target ) ) {
        return target.map(function( element ) {
          return new Memento( element );
        });
      }

      return [ new Memento( target ) ];
    },

    /**
     * Begin tracking a target.
     */
    begin: function( target ) {
      // Can't track nothing.
      if ( _.isEmpty( target ) ) {
        return;
      }

      this.previousState = this.snapshot( target );
      // Save if we don't have a baseline history.
      if ( !this.undoStack.length ) {
        this.save( target );
      }
    },

    /**
     * Stop tracking a target and push changes to history if anything changed.
     */
    end: function() {
      if ( !this.previousState ) {
        return;
      }

      // Get all targets that have changed since begin() was called.
      var targets = this.previousState.filter(function( memento ) {
        return !_.isEqual( memento.state, memento.target.toJSON() );
      }).map(function( memento ) {
        return memento.target;
      });

      // Save only if we have anything to save.
      if ( targets.length ) {
        // Don't save it as an array if there's only one object.
        this.save( targets );
      }
    },

    /**
     * Time travel towards the forwardStack and away from the backwardStack.
     */
    timeTravel: function( forwardStack, backwardStack ) {
      // Don't do anything if we can't time travel further.
      if ( !forwardStack.length ) {
        return;
      }

      if ( this.current ) {
        backwardStack.push( this.current );
      }

      this.current = forwardStack.pop();

      var that = this;
      this.current.forEach(function( memento ) {
        memento.restore();

        // Restore model references in mementos.
        if ( memento.target instanceof Backbone.Collection ) {
          that.reference( memento.target );
        }
      });

      return this;
    },

    undo: function() { return this.timeTravel( this.undoStack, this.redoStack ); },
    redo: function() { return this.timeTravel( this.redoStack, this.undoStack ); },

    clear: function() {
      this.undoStack = [];
      this.redoStack = [];
    },

    /**
     * Goes through the undo and redo stacks and rebuilds references to models.
     */
    reference: function( collection ) {
      this.undoStack.concat( this.redoStack ).forEach(function( state ) {
        state.forEach(function( memento ) {
          memento.reference( collection );
        });
      });
    }
  };

  return EditorHistory;
});
<|endoftext|>


<commit_before>"use strict";

var libxml = require( "libxmljs" ),
    url = require( 'url' ),
    path = require( 'path' ),
    fs = require( 'fs' ),
    Q = require( 'q' ),
    config = require( './config-model' ).server,
    client = require( 'redis' ).createClient( config.redis.cache.port, config.redis.cache.host, {
        auth_pass: config.redis.cache.password
    } ),
    utils = require( '../lib/utils' ),
    debug = require( 'debug' )( 'manifest-model' );

// in test environment, switch to different db
if ( process.env.NODE_ENV === 'test' ) {
    client.select( 15 );
}

function getManifest( html, lang ) {
    var hash, version, doc, resources, app, themesSupported, date,
        manifestKey = 'ma:' + lang + '_manifest',
        versionKey = 'ma:' + lang + '_version',
        deferred = Q.defer();

    // each language gets its own manifest
    client.get( manifestKey, function( error, manifest ) {
        if ( error ) {
            deferred.reject( error );
        } else if ( manifest && manifest !== 'null' ) {
            debug( 'getting manifest from cache' );
            deferred.resolve( manifest );
        } else {
            debug( 'building manifest from scratch' );
            doc = libxml.parseHtml( html );
            resources = [];
            app = require( '../../config/express' );
            themesSupported = app.get( 'themes supported' ) || [];

            // href attributes of link elements
            resources = resources.concat( _getLinkHrefs( doc ) );

            // additional themes
            resources = resources.concat( _getAdditionalThemes( resources, themesSupported ) );

            // translations
            resources = resources.concat( _getTranslations( lang ) );

            // any resources inside css files
            resources = resources.concat( _getResourcesFromCss( resources ) );

            // src attributes
            resources = resources.concat( _getSrcAttributes( doc ) );

            // remove non-existing files, empties, duplicates and non-http urls
            resources = resources
                .filter( _removeEmpties )
                .filter( _removeDuplicates )
                .filter( _removeNonHttpResources )
                .filter( _removeNonExisting );

            // calculate the hash to serve as the manifest version number
            hash = _calculateHash( html, resources );

            // determine version
            _getVersionObj( versionKey )
                .then( function( obj ) {
                    version = obj.version;
                    if ( obj.hash !== hash ) {
                        // create a new version
                        date = new Date().toISOString().replace( 'T', '|' );
                        version = date.substring( 0, date.length - 8 ) + '|' + lang;
                        // update stored version, don't wait for result
                        _updateVersionObj( versionKey, hash, version );
                    }
                    manifest = _getManifestString( version, resources );
                    // cache manifest for an hour, don't wait for result
                    client.set( manifestKey, manifest, 'EX', 1 * 60 * 60, function() {} );
                    deferred.resolve( manifest );
                } );
        }
    } );

    return deferred.promise;
}

function _getManifestString( version, resources ) {
    return 'CACHE MANIFEST\n' +
        '# version: ' + version + '\n' +
        '\n' +
        'CACHE:\n' +
        resources.join( '\n' ) + '\n' +
        '\n' +
        'FALLBACK:\n' +
        '/_ /offline\n' +
        '\n' +
        'NETWORK:\n' +
        '*\n';
}

function _getVersionObj( versionKey ) {
    var deferred = Q.defer();

    client.hgetall( versionKey, function( error, obj ) {
        debug( 'result', obj );
        if ( error ) {
            deferred.reject( error );
        } else if ( obj && obj.hash && obj.version ) {
            deferred.resolve( obj );
        } else {
            deferred.resolve( {} );
        }
    } );

    return deferred.promise;
}

function _updateVersionObj( versionKey, hash, version ) {
    client.hmset( versionKey, {
        hash: hash,
        version: version
    }, function( error ) {} );
}

function _getLinkHrefs( doc ) {
    return doc.find( '//link[@href]' ).map( function( element ) {
        return element.attr( 'href' ).value();
    } );
}

function _getSrcAttributes( doc ) {
    return doc.find( '//*[@src]' ).map( function( element ) {
        return element.attr( 'src' ).value();
    } );
}

function _getAdditionalThemes( resources, themes ) {
    var urls = [];

    resources.forEach( function( resource ) {
        var themeStyleSheet = /theme-([A-z]+)(\.print)?\.css$/;
        if ( themeStyleSheet.test( resource ) ) {
            var foundTheme = resource.match( themeStyleSheet )[ 1 ];
            themes.forEach( function( theme ) {
                var themeUrl = resource.replace( foundTheme, theme );
                urls.push( themeUrl );
            } );
        }
    } );

    return urls;
}

function _getTranslations( lang ) {
    return ( lang ) ? '/locales/' + lang + '/translation.json' : null;
}

function _getResourcesFromCss( resources ) {
    var content, matches,
        urlReg = /url\(['|"]?([^\)'"]+)['|"]?\)/g,
        cssReg = /^.+\.css$/,
        urls = [];

    resources.forEach( function( resource ) {
        if ( cssReg.test( resource ) ) {
            content = _getResourceContent( resource );
            while ( ( matches = urlReg.exec( content ) ) !== null ) {
                urls.push( matches[ 1 ] );
            }
        }
    } );

    return urls;
}

function _getResourceContent( resource ) {
    var rel;
    // in try catch in case css file is missing
    try {
        rel = ( resource.indexOf( '/locales/' ) === 0 ) ? '../../' : '../../public';
        return fs.readFileSync( path.join( __dirname, rel, url.parse( resource ).pathname ), 'utf8' );
    } catch ( e ) {
        return '';
    }
}

function _removeNonExisting( resource ) {
    var rel = ( resource.indexOf( '/locales/' ) === 0 ) ? '../../' : '../../public',
        resourcePath = path.join( __dirname, rel, url.parse( resource ).pathname ),
        // TODO: in later versions of node.js, this should be replaced by: fs.accessSync(resourcePath, fs.R_OK)
        exists = fs.existsSync( resourcePath );

    if ( !exists ) {
        debug( 'cannot find', resourcePath );
    }
    return exists;
}

function _removeEmpties( resource ) {
    return !!resource;
}

function _removeDuplicates( resource, position, array ) {
    return array.indexOf( resource ) == position;
}

function _removeNonHttpResources( resourceUrl ) {
    var parsedUrl = url.parse( resourceUrl );
    return parsedUrl.path && parsedUrl.protocol !== 'data:';
}

function _calculateHash( html, resources ) {
    var content,
        hash = utils.md5( html );

    resources.forEach( function( resource ) {
        try {
            content = _getResourceContent( resource );
            hash += utils.md5( content );
        } catch ( e ) {}
    } );

    // shorten hash
    return utils.md5( hash );
}

module.exports = {
    get: getManifest
};
<commit_msg>changed: manifest theme addition<commit_after>"use strict";

var libxml = require( "libxmljs" ),
    url = require( 'url' ),
    path = require( 'path' ),
    fs = require( 'fs' ),
    Q = require( 'q' ),
    config = require( './config-model' ).server,
    client = require( 'redis' ).createClient( config.redis.cache.port, config.redis.cache.host, {
        auth_pass: config.redis.cache.password
    } ),
    utils = require( '../lib/utils' ),
    debug = require( 'debug' )( 'manifest-model' );

// in test environment, switch to different db
if ( process.env.NODE_ENV === 'test' ) {
    client.select( 15 );
}

function getManifest( html, lang ) {
    var hash, version, doc, resources, themesSupported, date,
        manifestKey = 'ma:' + lang + '_manifest',
        versionKey = 'ma:' + lang + '_version',
        deferred = Q.defer();

    // each language gets its own manifest
    client.get( manifestKey, function( error, manifest ) {
        if ( error ) {
            deferred.reject( error );
        } else if ( manifest && manifest !== 'null' ) {
            debug( 'getting manifest from cache' );
            deferred.resolve( manifest );
        } else {
            debug( 'building manifest from scratch' );
            doc = libxml.parseHtml( html );
            resources = [];
            themesSupported = config[ 'themes supported' ] || [];

            // href attributes of link elements
            resources = resources.concat( _getLinkHrefs( doc ) );

            // additional themes
            resources = resources.concat( _getAdditionalThemes( resources, themesSupported ) );

            // translations
            resources = resources.concat( _getTranslations( lang ) );

            // any resources inside css files
            resources = resources.concat( _getResourcesFromCss( resources ) );

            // src attributes
            resources = resources.concat( _getSrcAttributes( doc ) );

            // remove non-existing files, empties, duplicates and non-http urls
            resources = resources
                .filter( _removeEmpties )
                .filter( _removeDuplicates )
                .filter( _removeNonHttpResources )
                .filter( _removeNonExisting );

            // calculate the hash to serve as the manifest version number
            hash = _calculateHash( html, resources );

            // determine version
            _getVersionObj( versionKey )
                .then( function( obj ) {
                    version = obj.version;
                    if ( obj.hash !== hash ) {
                        // create a new version
                        date = new Date().toISOString().replace( 'T', '|' );
                        version = date.substring( 0, date.length - 8 ) + '|' + lang;
                        // update stored version, don't wait for result
                        _updateVersionObj( versionKey, hash, version );
                    }
                    manifest = _getManifestString( version, resources );
                    // cache manifest for an hour, don't wait for result
                    client.set( manifestKey, manifest, 'EX', 1 * 60 * 60, function() {} );
                    deferred.resolve( manifest );
                } );
        }
    } );

    return deferred.promise;
}

function _getManifestString( version, resources ) {
    return 'CACHE MANIFEST\n' +
        '# version: ' + version + '\n' +
        '\n' +
        'CACHE:\n' +
        resources.join( '\n' ) + '\n' +
        '\n' +
        'FALLBACK:\n' +
        '/_ /offline\n' +
        '\n' +
        'NETWORK:\n' +
        '*\n';
}

function _getVersionObj( versionKey ) {
    var deferred = Q.defer();

    client.hgetall( versionKey, function( error, obj ) {
        debug( 'result', obj );
        if ( error ) {
            deferred.reject( error );
        } else if ( obj && obj.hash && obj.version ) {
            deferred.resolve( obj );
        } else {
            deferred.resolve( {} );
        }
    } );

    return deferred.promise;
}

function _updateVersionObj( versionKey, hash, version ) {
    client.hmset( versionKey, {
        hash: hash,
        version: version
    }, function( error ) {} );
}

function _getLinkHrefs( doc ) {
    return doc.find( '//link[@href]' ).map( function( element ) {
        return element.attr( 'href' ).value();
    } );
}

function _getSrcAttributes( doc ) {
    return doc.find( '//*[@src]' ).map( function( element ) {
        return element.attr( 'src' ).value();
    } );
}

function _getAdditionalThemes( resources, themes ) {
    var urls = [];

    resources.forEach( function( resource ) {
        var themeStyleSheet = /theme-([A-z]+)(\.print)?\.css$/;
        if ( themeStyleSheet.test( resource ) ) {
            var foundTheme = resource.match( themeStyleSheet )[ 1 ];
            themes.forEach( function( theme ) {
                var themeUrl = resource.replace( foundTheme, theme );
                urls.push( themeUrl );
            } );
        }
    } );

    return urls;
}

function _getTranslations( lang ) {
    return ( lang ) ? '/locales/' + lang + '/translation.json' : null;
}

function _getResourcesFromCss( resources ) {
    var content, matches,
        urlReg = /url\(['|"]?([^\)'"]+)['|"]?\)/g,
        cssReg = /^.+\.css$/,
        urls = [];

    resources.forEach( function( resource ) {
        if ( cssReg.test( resource ) ) {
            content = _getResourceContent( resource );
            while ( ( matches = urlReg.exec( content ) ) !== null ) {
                urls.push( matches[ 1 ] );
            }
        }
    } );

    return urls;
}

function _getResourceContent( resource ) {
    var rel;
    // in try catch in case css file is missing
    try {
        rel = ( resource.indexOf( '/locales/' ) === 0 ) ? '../../' : '../../public';
        return fs.readFileSync( path.join( __dirname, rel, url.parse( resource ).pathname ), 'utf8' );
    } catch ( e ) {
        return '';
    }
}

function _removeNonExisting( resource ) {
    var rel = ( resource.indexOf( '/locales/' ) === 0 ) ? '../../' : '../../public',
        resourcePath = path.join( __dirname, rel, url.parse( resource ).pathname ),
        // TODO: in later versions of node.js, this should be replaced by: fs.accessSync(resourcePath, fs.R_OK)
        exists = fs.existsSync( resourcePath );

    if ( !exists ) {
        debug( 'cannot find', resourcePath );
    }
    return exists;
}

function _removeEmpties( resource ) {
    return !!resource;
}

function _removeDuplicates( resource, position, array ) {
    return array.indexOf( resource ) == position;
}

function _removeNonHttpResources( resourceUrl ) {
    var parsedUrl = url.parse( resourceUrl );
    return parsedUrl.path && parsedUrl.protocol !== 'data:';
}

function _calculateHash( html, resources ) {
    var content,
        hash = utils.md5( html );

    resources.forEach( function( resource ) {
        try {
            content = _getResourceContent( resource );
            hash += utils.md5( content );
        } catch ( e ) {}
    } );

    // shorten hash
    return utils.md5( hash );
}

module.exports = {
    get: getManifest
};
<|endoftext|>


<commit_before>import { default as React, Component } from 'react';
import { render } from 'react-dom';
import { Modal } from 'react-bootstrap';
import { authOperation, authEmitter } from '../service/authOperation';

export class SubscribeModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      profile: false,
      subscribeOption: 'major'
    };
    this.options = {
      option1: {
        value: 'major',
        text: 'New GEM releases'
      },
      option2: {
        value: 'all',
        text: 'Limited major updates'
      }
    }
    this.init();
  }
  init() {
    authEmitter.addListener('profile', (data) => {
      this.setState({
        profile: data
      });
    });
    setTimeout(() => {
      if(!this.state.profile) {
        this.open();
      }
    }, 1000*60*1);
  }
  close() {
    this.internalClose = true;
    this.setState({ showModal: false });
  }
  open() {
    if(!this.state.profile) {
      this.setState({ showModal: true });
    }
  }
  subscribe() {
    authOperation.login(this.state.subscribeOption);
  }
  subscribeOptionChange(value) {
    this.setState({
      subscribeOption: value
    });
  }
  showIcon() {
    let icon = ();
    if(this.state.profile) {
      icon = ();
    }
    return icon;
  }
  render() {
    return (

         this.open()}>
          {this.showIcon()}

        <Modal className="modal-info" show={this.state.showModal} onHide={() => this.close()}>
          <Modal.Header closeButton>
            <Modal.Title>Be in the know about major updates!</Modal.Title>
          </Modal.Header>
          <Modal.Body>

                      <input type="radio"
                        checked={this.state.subscribeOption === this.options.option1.value}
                        onChange={() => this.subscribeOptionChange(this.options.option1.value)}
                        name="subscribeOption" id="subscribeOption" value={this.options.option1.value} /> {this.options.option1.text}

                      <input type="radio"
                        checked={this.state.subscribeOption === this.options.option2.value}
                        onChange={() => this.subscribeOptionChange(this.options.option2.value)}
                        name="subscribeOption1" id="subscribeOption1" value={this.options.option2.value} /> {this.options.option2.text}

              <button className="btn btn-primary" onClick={() => this.subscribe()}>
                 Subscribe with Github
              </button>

          </Modal.Body>
        </Modal>

    )
  }
}
<commit_msg>implement modal popup timer incremeant<commit_after>import { default as React, Component } from 'react';
import { storageService } from '../service/StorageService';
import { render } from 'react-dom';
import { Modal } from 'react-bootstrap';
import { authOperation, authEmitter } from '../service/authOperation';

export class SubscribeModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      profile: false,
      subscribeOption: 'major'
    };
    this.options = {
      option1: {
        value: 'major',
        text: 'New GEM releases'
      },
      option2: {
        value: 'all',
        text: 'Limited major updates'
      }
    }
    this.timer = 1;
    this.init();
  }
  init() {
    authEmitter.addListener('profile', (data) => {
      this.setState({
        profile: data
      });
    });
    if(storageService.get('popuptimer')) {
      this.timer = parseInt(storageService.get('popuptimer'));
    }
    setTimeout(() => {
      if(!this.state.profile) {
        this.open();
      }
    }, 1000*60*this.timer);
  }
  close() {
    this.internalClose = true;
    storageService.set('popuptimer', this.timer+5);
    this.setState({ showModal: false });
  }
  open() {
    if(!this.state.profile) {
      this.setState({ showModal: true });
    }
  }
  subscribe() {
    authOperation.login(this.state.subscribeOption);
  }
  subscribeOptionChange(value) {
    this.setState({
      subscribeOption: value
    });
  }
  showIcon() {
    let icon = ();
    if(this.state.profile) {
      icon = ();
    }
    return icon;
  }
  render() {
    return (

         this.open()}>
          {this.showIcon()}

        <Modal className="modal-info" show={this.state.showModal} onHide={() => this.close()}>
          <Modal.Header closeButton>
            <Modal.Title>Be in the know about major updates!</Modal.Title>
          </Modal.Header>
          <Modal.Body>

                      <input type="radio"
                        checked={this.state.subscribeOption === this.options.option1.value}
                        onChange={() => this.subscribeOptionChange(this.options.option1.value)}
                        name="subscribeOption" id="subscribeOption" value={this.options.option1.value} /> {this.options.option1.text}

                      <input type="radio"
                        checked={this.state.subscribeOption === this.options.option2.value}
                        onChange={() => this.subscribeOptionChange(this.options.option2.value)}
                        name="subscribeOption1" id="subscribeOption1" value={this.options.option2.value} /> {this.options.option2.text}

              <button className="btn btn-primary" onClick={() => this.subscribe()}>
                 Subscribe with Github
              </button>

          </Modal.Body>
        </Modal>

    )
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2017-2018 Micro Focus or one of its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// defines the structure representing the tenantConfig table in the database
const Sequelize = require("sequelize");
const globalConfigTableDetails = require('./globalConfig.js')

var tableDefinition = {
    tenantId: {
        allowNull: false,
        field: "tenant_id",
        primaryKey: true,
        type: Sequelize.STRING(40)
    },
    key: {
        allowNull: false,
        field: "key",
        primaryKey: true,
        references: {
            key: globalConfigTableDetails.definition.key.field,
            model: globalConfigTableDetails.tableName
        },
        type: Sequelize.STRING(255)
    },
    value: {
        allowNull: false,
        field: "value",
        type: Sequelize.TEXT
    }
};

module.exports = {
    definition: tableDefinition,
    name: "globalConfig",
    tableName: "tbl_tenant_config"
};
<commit_msg>Corrected the name of the tenant table in the tenantConfig.js file. (#51)<commit_after>/*
 * Copyright 2017-2018 Micro Focus or one of its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// defines the structure representing the tenantConfig table in the database
const Sequelize = require("sequelize");
const globalConfigTableDetails = require('./globalConfig.js')

var tableDefinition = {
    tenantId: {
        allowNull: false,
        field: "tenant_id",
        primaryKey: true,
        type: Sequelize.STRING(40)
    },
    key: {
        allowNull: false,
        field: "key",
        primaryKey: true,
        references: {
            key: globalConfigTableDetails.definition.key.field,
            model: globalConfigTableDetails.tableName
        },
        type: Sequelize.STRING(255)
    },
    value: {
        allowNull: false,
        field: "value",
        type: Sequelize.TEXT
    }
};

module.exports = {
    definition: tableDefinition,
    name: "tenantConfig",
    tableName: "tbl_tenant_config"
};
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc run config
 * @name blimpCockpitApp.routeProvider
 * @description
 * route provider of the blimpCockpitApp
 */
angular.module('blimpCockpitApp')
  .run(['$state', '$rootScope', 'cockpitApi', '$interval',
    function ($state, $rootScope, cockpitApi, $interval) {

      $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {

        var requireLogin = toState.data.requireLogin;
        cockpitApi.getCurrentUser().then(function (res) {

          if (requireLogin && res.id == undefined && !$state.includes('access.forgotpwd')) {
            $state.go('access.signin');
          }

          if(($state.includes('access.forgotpwd') || $state.includes('access.signin')) && res.id!=undefined){

            $state.go('app.cockpit');
          }
        }, function () {
          console.log('error')
        });

      });

    }])
  .run(
  ['$rootScope', '$state', '$stateParams',
    function ($rootScope, $state, $stateParams) {
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
    }
  ]
)
  .config(
  ['$stateProvider', '$urlRouterProvider', 'JQ_CONFIG',
    function ($stateProvider, $urlRouterProvider, JQ_CONFIG) {

      $urlRouterProvider.otherwise('access/signin');
      $stateProvider
        .state('app', {
          abstract: true,
          url: '/app',
          templateUrl: 'views/app.html',
          data: {
            requireLogin: true
          }
        })
        .state('app.cockpit', {
          url: '/cockpit',
          templateUrl: 'views/app_dashboard.html',
          resolve: {
            deps: ['uiLoad',
              function (uiLoad) {
                return uiLoad.load(
                  JQ_CONFIG.fullcalendar.concat('scripts/controllers/calendar.js')
                )
              }]
          }
        })

        // mail
        .state('app.mail', {
          abstract: true,
          url: '/mail',
          templateUrl: 'views/mail.html'
        })
        .state('app.mail.list', {
          url: '/inbox/{fold}',
          templateUrl: 'views/mail.list.html'
        })
        .state('app.mail.detail', {
          url: '/{mailId:[0-9]{1,4}}',
          templateUrl: 'views/mail.detail.html'
        })
        .state('app.mail.compose', {
          url: '/compose',
          templateUrl: 'views/mail.new.html'
        })

        // fullCalendar
        .state('app.calendar', {
          url: '/calendar',
          templateUrl: 'views/app_calendar.html',
          resolve: {
            deps: ['uiLoad',
              function (uiLoad) {
                return uiLoad.load(
                  JQ_CONFIG.fullcalendar.concat('scripts/controllers/calendar.js')
                )
              }]
          }
        })

        .state('apps', {
          abstract: true,
          url: '/apps',
          templateUrl: 'views/layout.html',
          data: {
            requireLogin: true
          }
        })
        .state('apps.note', {
          url: '/note',
          templateUrl: 'views/apps_note.html'

        })
        .state('apps.contact', {
          url: '/contact',
          templateUrl: 'views/apps_contact.html'
        })
        .state('app.todo', {
          url: '/todo',
          templateUrl: 'views/apps_todo.html'

        })
        .state('app.todo.list', {
          url: '/{fold}'
        })

        .state('access', {
          url: '/access',
          template: '

',
          data: {
            requireLogin: false
          }
        })
        .state('access.signin', {
          url: '/signin',
          templateUrl: 'views/page_signin.html'

        })
        .state('access.signup', {
          url: '/signup',
          templateUrl: 'views/page_signup.html'

        })
        .state('access.forgotpwd', {
          url: '/forgotpwd',
          templateUrl: 'views/page_forgotpwd.html'
        })

    }
  ]
);
<commit_msg>updated to check if user is on pword screen<commit_after>'use strict';

/**
 * @ngdoc run config
 * @name blimpCockpitApp.routeProvider
 * @description
 * route provider of the blimpCockpitApp
 */
angular.module('blimpCockpitApp')
  .run(['$state', '$rootScope', 'cockpitApi', '$interval',
    function ($state, $rootScope, cockpitApi, $interval) {

      $rootScope.$on('$stateChangeStart', function (event, toState, toParams) {

        var requireLogin = toState.data.requireLogin;
        cockpitApi.getCurrentUser().then(function (res) {

          if (requireLogin && res.id == undefined && !$state.includes('access.forgotpwd')) {
            $state.go('access.signin');
          }

          if(($state.includes('access.forgotpwd') || $state.includes('access.signin')) && res.id!=undefined){

            $state.go('app.cockpit');
          }
        }, function () {
          console.log('error')
        });

      });

    }])
  .run(
  ['$rootScope', '$state', '$stateParams',
    function ($rootScope, $state, $stateParams) {
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
    }
  ]
)
  .config(
  ['$stateProvider', '$urlRouterProvider', 'JQ_CONFIG',
    function ($stateProvider, $urlRouterProvider, JQ_CONFIG) {

      $urlRouterProvider.otherwise('access/signin');
      $stateProvider
        .state('app', {
          abstract: true,
          url: '/app',
          templateUrl: 'views/app.html',
          data: {
            requireLogin: true
          }
        })
        .state('app.cockpit', {
          url: '/cockpit',
          templateUrl: 'views/app_dashboard.html',
          resolve: {
            deps: ['uiLoad',
              function (uiLoad) {
                return uiLoad.load(
                  JQ_CONFIG.fullcalendar.concat('scripts/controllers/calendar.js')
                )
              }]
          }
        })

        // mail
        .state('app.mail', {
          abstract: true,
          url: '/mail',
          templateUrl: 'views/mail.html'
        })
        .state('app.mail.list', {
          url: '/inbox/{fold}',
          templateUrl: 'views/mail.list.html'
        })
        .state('app.mail.detail', {
          url: '/{mailId:[0-9]{1,4}}',
          templateUrl: 'views/mail.detail.html'
        })
        .state('app.mail.compose', {
          url: '/compose',
          templateUrl: 'views/mail.new.html'
        })

        // fullCalendar
        .state('app.calendar', {
          url: '/calendar',
          templateUrl: 'views/app_calendar.html',
          resolve: {
            deps: ['uiLoad',
              function (uiLoad) {
                return uiLoad.load(
                  JQ_CONFIG.fullcalendar.concat('scripts/controllers/calendar.js')
                )
              }]
          }
        })

        .state('apps', {
          abstract: true,
          url: '/apps',
          templateUrl: 'views/layout.html',
          data: {
            requireLogin: true
          }
        })
        .state('apps.note', {
          url: '/note',
          templateUrl: 'views/apps_note.html'

        })
        .state('apps.contact', {
          url: '/contact',
          templateUrl: 'views/apps_contact.html'
        })
        .state('app.todo', {
          url: '/todo',
          templateUrl: 'views/apps_todo.html'

        })
        .state('app.todo.list', {
          url: '/{fold}'
        })

        .state('access', {
          url: '/access',
          template: '

',
          data: {
            requireLogin: false
          }
        })
        .state('access.signin', {
          url: '/signin',
          templateUrl: 'views/page_signin.html'

        })
        .state('access.signup', {
          url: '/signup',
          templateUrl: 'views/page_signup.html'

        })
        .state('access.forgotpwd', {
          url: '/forgotpwd',
          templateUrl: 'views/page_forgotpwd.html'
        })

    }
  ]
);
<|endoftext|>