<commit_before>;
/**
 *
 * @summary 经纬平台
 * */
function jingweiplatform() {

}

/**
 *
 * @summary 获取上期期号
 * @return {String} 期号 如：20161120-032
 * */
jingweiplatform.prototype.getLastPeriodNumberString = function () {
    var periodNumber = $('#t_code_sn').text();
    var dateString = moment().format("YYYYMMDD");
    return dateString + '-' + periodNumber;
};

/**
 *
 * @summary 获取当前期号
 * @return {String} 期号 如：20161120-032
 * */
jingweiplatform.prototype.getCurrentPeriodNumberString = function () {
    var currentPeriodNumber = $('#t_issue_sn').text();
    var dateString = moment().format("YYYYMMDD");
    return dateString + '-' + currentPeriodNumber;
};

/**
 *
 * @summary 获取当前账户余额
 * @return {Number} 当前账户余额
 * */
jingweiplatform.prototype.getCurrentAccountBalance = function () {
    var accountBalance = $('#t_user_cash').text();
    return parseFloat(accountBalance);
};

/**
 *
 * @summary 获取上期开奖号码
 * @return {Number} 上期开奖号码 如：58903
 * */
jingweiplatform.prototype.getLastPrizeNumber = function () {
    var number = $('#t_code_code').text().split(' ').join('');
    return Number(number);
};

/**
 *
 * @summary 执行投注 必须实现的接口方法
 * @param {String} investNumberString 需要投注的号码
 * */
jingweiplatform.prototype.execInvest = function (investNumberString) {
    var self = this;
    //后二直选投注
    self.houErZhiXuanInvest(investNumberString);
};

/**
 *
 * 后二直选投注
 * */
jingweiplatform.prototype.houErZhiXuanInvest = function (investNumberString) {
    //关闭提示框
    $('body > div:nth-child(18) > div:nth-child(4) > span').click();
    //后二
    $("#pmrange > li:nth-child(8)").click();
    //只选单式
    $('#subpms > div:nth-child(1) > ul > li:nth-child(2)').click();
    //选择分模式
    $('#extra_area > div:nth-child(4) > ul > li:nth-child(4)').click();
    //填充号码
    $('#betarea > div > textarea').val(investNumberString);
    //添加到投注
    $('#extra_area > div:nth-child(1) > img').click();
    //确认投注
    $('#bets_list_area > div > div:nth-child(1) > img').click();
};

/**
 *
 * 后一投注
 * */
jingweiplatform.prototype.houYiInvest = function (investNumberString) {
    //关闭提示框
    $('body > div:nth-child(18) > div:nth-child(4) > span').click();
    //定位胆
    $("#pmrange > li:nth-child(9)").click();
    //个位
    $('#subpms > div > ul > li:nth-child(6)').click();
    //选择分模式
    $('#extra_area > div:nth-child(4) > ul > li:nth-child(4)').click();
    //选号码
    for (var i = 0; i < investNumberString.length; i++) {
        var item = investNumberString[i];
        switch (item) {
            case '0':
                $('#betarea > div > div > ul > li:nth-child(1)').click();
                break;
            case '1':
                $('#betarea > div > div > ul > li:nth-child(2)').click();
                break;
            case '2':
                $('#betarea > div > div > ul > li:nth-child(3)').click();
                break;
            case '3':
                $('#betarea > div > div > ul > li:nth-child(4)').click();
                break;
            case '4':
                $('#betarea > div > div > ul > li:nth-child(5)').click();
                break;
            case '5':
                $('#betarea > div > div > ul > li:nth-child(6)').click();
                break;
            case '6':
                $('#betarea > div > div > ul > li:nth-child(7)').click();
                break;
            case '7':
                $('#betarea > div > div > ul > li:nth-child(8)').click();
                break;
            case '8':
                $('#betarea > div > div > ul > li:nth-child(9)').click();
                break;
            case '9':
                $('#betarea > div > div > ul > li:nth-child(10)').click();
                break;
        }
    }
    //添加到投注
    $('#extra_area > div:nth-child(1) > img').click();
    //确认投注
    $('#bets_list_area > div > div:nth-child(1) > img').click();
};<commit_msg>added new function.<commit_after>;
/**
 *
 * @summary 经纬平台
 * */
function jingweiplatform() {

}

/**
 *
 * @summary 获取上期期号
 * @return {String} 期号 如：20161120-032
 * */
jingweiplatform.prototype.getLastPeriodNumberString = function () {
    var periodNumber = $('#t_code_sn').text();
    var dateString = moment().format("YYYYMMDD");
    return dateString + '-' + periodNumber;
};

/**
 *
 * @summary 获取当前期号
 * @return {String} 期号 如：20161120-032
 * */
jingweiplatform.prototype.getCurrentPeriodNumberString = function () {
    var currentPeriodNumber = $('#t_issue_sn').text();
    var dateString = moment().format("YYYYMMDD");
    return dateString + '-' + currentPeriodNumber;
};

/**
 *
 * @summary 获取当前账户余额
 * @return {Number} 当前账户余额
 * */
jingweiplatform.prototype.getCurrentAccountBalance = function () {
    var accountBalance = $('#t_user_cash').text();
    return parseFloat(accountBalance);
};

/**
 *
 * @summary 获取上期开奖号码
 * @return {Number} 上期开奖号码 如：58903
 * */
jingweiplatform.prototype.getLastPrizeNumber = function () {
    var number = $('#t_code_code').text().split(' ').join('');
    return Number(number);
};

/**
 *
 * @summary 执行投注 必须实现的接口方法
 * @param {String} investNumberString 需要投注的号码
 * */
jingweiplatform.prototype.execInvest = function (investNumberString) {
    var self = this;
    //后二直选投注
    self.houErZhiXuanInvest(investNumberString);
};

/**
 *
 * 后二直选投注
 * */
jingweiplatform.prototype.houErZhiXuanInvest = function (investNumberString) {
    //关闭提示框
    $('body > div:nth-child(18) > div:nth-child(4) > span').click();
    //后二
    $("#pmrange > li:nth-child(8)").click();
    //只选单式
    $('#subpms > div:nth-child(1) > ul > li:nth-child(2)').click();
    //选择分模式
    $('#extra_area > div:nth-child(4) > ul > li:nth-child(4)').click();
    //填充号码
    $('#betarea > div > textarea').val(investNumberString);
    //设置投注倍数
    $('#extra_area > div:nth-child(5) > input[type="text"]').val(2);
    //添加到投注
    $('#extra_area > div:nth-child(1) > img').click();
    //确认投注
    $('#bets_list_area > div > div:nth-child(1) > img').click();
};

/**
 *
 * 后一投注
 * */
jingweiplatform.prototype.houYiInvest = function (investNumberString) {
    //关闭提示框
    $('body > div:nth-child(18) > div:nth-child(4) > span').click();
    //定位胆
    $("#pmrange > li:nth-child(9)").click();
    //个位
    $('#subpms > div > ul > li:nth-child(6)').click();
    //选择分模式
    $('#extra_area > div:nth-child(4) > ul > li:nth-child(4)').click();
    //选号码
    for (var i = 0; i < investNumberString.length; i++) {
        var item = investNumberString[i];
        switch (item) {
            case '0':
                $('#betarea > div > div > ul > li:nth-child(1)').click();
                break;
            case '1':
                $('#betarea > div > div > ul > li:nth-child(2)').click();
                break;
            case '2':
                $('#betarea > div > div > ul > li:nth-child(3)').click();
                break;
            case '3':
                $('#betarea > div > div > ul > li:nth-child(4)').click();
                break;
            case '4':
                $('#betarea > div > div > ul > li:nth-child(5)').click();
                break;
            case '5':
                $('#betarea > div > div > ul > li:nth-child(6)').click();
                break;
            case '6':
                $('#betarea > div > div > ul > li:nth-child(7)').click();
                break;
            case '7':
                $('#betarea > div > div > ul > li:nth-child(8)').click();
                break;
            case '8':
                $('#betarea > div > div > ul > li:nth-child(9)').click();
                break;
            case '9':
                $('#betarea > div > div > ul > li:nth-child(10)').click();
                break;
        }
    }
    //添加到投注
    $('#extra_area > div:nth-child(1) > img').click();
    //确认投注
    $('#bets_list_area > div > div:nth-child(1) > img').click();
};<|endoftext|>


<commit_before>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var util = require('./util')
  , toArray = util.toArray;

/**
 * Log levels.
 */

var levels = [
    'error'
  , 'warn'
  , 'info'
  , 'debug'
];

/**
 * Colors for log levels.
 */

var colors = [
    31
  , 33
  , 36
  , 90
];

/**
 * Pads the nice output to the longest log level.
 */

function pad (str) {
  var max = 0;

  for (var i = 0, l = levels.length; i < l; i++)
    max = Math.max(max, levels[i].length);

  if (str.length < max)
    return str + new Array(max - str.length + 1).join(' ');

  return str;
};

/**
 * Returns a human readable timestamp.
 */

function timestamp() {

  function pad_date(number) {

    return ('0' + number).slice(-2)

  }

  var date = new Date();

  return date.getFullYear() + "-" + pad_date(date.getMonth()+1) + "-" + pad_date(date.getDate()) + " " + date.toLocaleTimeString() + " ";
};

/**
 * Logger (console).
 *
 * @api public
 */

var Logger = module.exports = function (opts) {
  opts = opts || {}
  this.colors = false !== opts.colors;
  this.level = 3;
  this.enabled = true;
};

/**
 * Log method.
 *
 * @api public
 */

Logger.prototype.log = function (type) {
  var index = levels.indexOf(type);

  if (index > this.level || !this.enabled)
    return this;

  if (this.timestamps)
    type = timestamp() + type;

  console.log.apply(
      console
    , [this.colors
        ? '   \033[' + colors[index] + 'm' + pad(type) + ' -\033[39m'
        : type + ':'
      ].concat(toArray(arguments).slice(1))
  );

  return this;
};

/**
 * Generate methods.
 */

levels.forEach(function (name) {
  Logger.prototype[name] = function () {
    this.log.apply(this, [name].concat(toArray(arguments)));
  };
});
<commit_msg>adding timestamps option to logger module exports<commit_after>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var util = require('./util')
  , toArray = util.toArray;

/**
 * Log levels.
 */

var levels = [
    'error'
  , 'warn'
  , 'info'
  , 'debug'
];

/**
 * Colors for log levels.
 */

var colors = [
    31
  , 33
  , 36
  , 90
];

/**
 * Pads the nice output to the longest log level.
 */

function pad (str) {
  var max = 0;

  for (var i = 0, l = levels.length; i < l; i++)
    max = Math.max(max, levels[i].length);

  if (str.length < max)
    return str + new Array(max - str.length + 1).join(' ');

  return str;
};

/**
 * Returns a human readable timestamp.
 */

function timestamp() {

  function pad_date(number) {

    return ('0' + number).slice(-2)

  }

  var date = new Date();

  return date.getFullYear() + "-" + pad_date(date.getMonth()+1) + "-" + pad_date(date.getDate()) + " " + date.toLocaleTimeString() + " ";
};

/**
 * Logger (console).
 *
 * @api public
 */

var Logger = module.exports = function (opts) {
  opts = opts || {}
  this.timestamps = false;
  this.colors = false !== opts.colors;
  this.level = 3;
  this.enabled = true;
};

/**
 * Log method.
 *
 * @api public
 */

Logger.prototype.log = function (type) {
  var index = levels.indexOf(type);

  if (index > this.level || !this.enabled)
    return this;

  if (this.timestamps)
    type = timestamp() + type;

  console.log.apply(
      console
    , [this.colors
        ? '   \033[' + colors[index] + 'm' + pad(type) + ' -\033[39m'
        : type + ':'
      ].concat(toArray(arguments).slice(1))
  );

  return this;
};

/**
 * Generate methods.
 */

levels.forEach(function (name) {
  Logger.prototype[name] = function () {
    this.log.apply(this, [name].concat(toArray(arguments)));
  };
});
<|endoftext|>


<commit_before>import '../google-analytics.js';
import { setupNavbar } from './navbar.js';
import { setupExtensionButton } from './extension.js';
import { setupLibraries } from './libraries.js';
import { setupTokenEditor, setTokenEditorValue } from '../editor';
import { setupJwtCounter } from './counter.js';
import { setupSmoothScrolling } from './smooth-scrolling.js';
import { setupHighlighting } from './highlighting.js';
import { isChrome, isFirefox } from './utils.js';
import { setupShareJwtButton } from '../share-button.js';
import {
  publicKeyTextArea,
  codeElements,
  debuggerSection,
  extensionSection,
  ebookSection,
  shareJwtButton,
  shareJwtTextElement
} from './dom-elements.js';

import queryString from 'querystring';

/* For initialization, look at the end of this file */

function parseLocationQuery() {
  const locSearch = queryString.parse(document.location.search.substr(1));
  const locHash = queryString.parse(document.location.hash.substr(1));

  const keys = [
    'id_token',
    'access_token',
    'value',
    'token',
    'debugger-io?token'
  ];
  for(const key of keys) {
    const token = locSearch[key] || locHash[key];

    if(token) {
      setTokenEditorValue(token);

      if(locSearch.publicKey) {
        publicKeyTextArea.value = locSearch.publicKey;
      }

      debuggerSection.scrollIntoView(true);

      break;
    }
  }
}

function pickEbookOrExtensionBanner() {
  if((isChrome() || isFirefox()) && (Math.random() >= 0.5)) {
    extensionSection.style.display = 'block';
  } else {
    ebookSection.style.display = 'block';
  }
}

// Initialization
setupNavbar();
setupExtensionButton();
setupSmoothScrolling();
setupLibraries();
setupTokenEditor();
parseLocationQuery();
setupHighlighting();
setupJwtCounter();
pickEbookOrExtensionBanner();
setupShareJwtButton(shareJwtButton, shareJwtTextElement);
<commit_msg>Fix public key loading for tokens in location hash.<commit_after>import '../google-analytics.js';
import { setupNavbar } from './navbar.js';
import { setupExtensionButton } from './extension.js';
import { setupLibraries } from './libraries.js';
import { setupTokenEditor, setTokenEditorValue } from '../editor';
import { setupJwtCounter } from './counter.js';
import { setupSmoothScrolling } from './smooth-scrolling.js';
import { setupHighlighting } from './highlighting.js';
import { isChrome, isFirefox } from './utils.js';
import { setupShareJwtButton } from '../share-button.js';
import {
  publicKeyTextArea,
  debuggerSection,
  extensionSection,
  ebookSection,
  shareJwtButton,
  shareJwtTextElement
} from './dom-elements.js';

import queryString from 'querystring';

/* For initialization, look at the end of this file */

function parseLocationQuery() {
  const locSearch = queryString.parse(document.location.search.substr(1));
  const locHash = queryString.parse(document.location.hash.substr(1));

  const keys = [
    'id_token',
    'access_token',
    'value',
    'token',
    'debugger-io?token'
  ];
  for(const key of keys) {
    const token = locSearch[key] || locHash[key];

    if(token) {
      setTokenEditorValue(token);

      if(locSearch.publicKey || locHash.publicKey) {
        publicKeyTextArea.value = locSearch.publicKey || locHash.publicKey;
      }

      debuggerSection.scrollIntoView(true);

      break;
    }
  }
}

function pickEbookOrExtensionBanner() {
  if((isChrome() || isFirefox()) && (Math.random() >= 0.5)) {
    extensionSection.style.display = 'block';
  } else {
    ebookSection.style.display = 'block';
  }
}

// Initialization
setupNavbar();
setupExtensionButton();
setupSmoothScrolling();
setupLibraries();
setupTokenEditor();
parseLocationQuery();
setupHighlighting();
setupJwtCounter();
pickEbookOrExtensionBanner();
setupShareJwtButton(shareJwtButton, shareJwtTextElement);
<|endoftext|>


<commit_before>$(function () {
  var map = null,
      checkedIds = [], //< list of tweet ids we've checked
      appendedCount = 0, //< number of tweets we successfully appended
      searchTerm = "", //< last search term
      searching = false,
      currentXhr = null, //< an ajax request reference if we need to cancel

      twitterButtonHtml = 'Tweet


<commit_before>/* Copyright (C) 2017 Canonical Ltd. */
'use strict';

const React = require('react');

const HashLink = require('./hash-link');
const SvgIcon = require('../svg-icon/svg-icon');

const jsTestUtils = require('../../utils/component-test-utils');

describe('HashLink', () => {

  it('can render', () => {
    const renderer = jsTestUtils.shallowRender(
      <HashLink
        changeState={sinon.stub()}
        hash="readme" />, true);
    const instance = renderer.getMountedInstance();
    const output = renderer.getRenderOutput();
    const expected = (

        <SvgIcon
          name="anchor_16"
          size="16" />

);
    expect(output).toEqualJSX(expected);
  });

  it('can change the has state', () => {
    const changeState = sinon.stub();
    const renderer = jsTestUtils.shallowRender(
      <HashLink
        changeState={changeState}
        hash="readme" />, true);
    const output = renderer.getRenderOutput();
    output.props.onClick();
    assert.equal(changeState.callCount, 1);
    assert.deepEqual(changeState.args[0][0], {
      hash: 'readme'
    });
  });
});
<commit_msg>Update hash link tests to use enzyme.<commit_after>/* Copyright (C) 2017 Canonical Ltd. */
'use strict';

const React = require('react');
const enzyme = require('enzyme');

const HashLink = require('./hash-link');
const SvgIcon = require('../svg-icon/svg-icon');

describe('HashLink', () => {

  const renderComponent = (options = {}) => enzyme.shallow(
    <HashLink
      changeState={options.changeState || sinon.stub()}
      hash={options.hash || 'readme'} />
  );

  it('can render', () => {
    const wrapper = renderComponent();
    const expected = (

        <SvgIcon
          name="anchor_16"
          size="16" />

);
    assert.compareJSX(wrapper, expected);
  });

  it('can change the hash state', () => {
    const changeState = sinon.stub();
    const wrapper = renderComponent({ changeState });
    wrapper.props().onClick();
    assert.equal(changeState.callCount, 1);
    assert.deepEqual(changeState.args[0][0], {
      hash: 'readme'
    });
  });
});
<|endoftext|>


<commit_before>var freebase = (function() {
    var freebase = {};
    var miniTopicFloaterEl = $("#miniTopicFloater");
    freebase.link = function(name, id) {
        var linkVal = node("a", name, {target:'_blank',href:freebase_url + '/view' + id})
        return miniTopicFloater(linkVal, id);

        function miniTopicFloater(element, id) {
            var mouseIsOver = false;
            element.bind("mouseover",function() {
                mouseIsOver = true;
                miniTopicFloaterEl.empty().freebaseMiniTopic(id, function(){
                    if (mouseIsOver)
                        miniTopicFloaterEl.show();
                });
            })
            element.bind("mouseout", function() {
                mouseIsOver = false;
                miniTopicFloaterEl.hide();
            })
            element.mousemove(function(e){
                miniTopicFloaterEl.css({
                    top: (e.pageY + 15) + "px",
                    left: (e.pageX + 15) + "px"
                });
            });
            return element;
        }
    };

    // Simple mql read
    freebase.mqlRead = function mqlRead(envelope, handler) {
        $.getJSON(getMqlReadURL(envelope), null, handler);
    };

    /* Used below, thus the odd style above */
    function getMqlReadURL(envelope) {
        var param = {query:JSON.stringify(envelope)};
        if (!('query' in envelope))
            param = {queries:param.query};
        return freebase_url + "/api/service/mqlread?callback=?&" + $.param(param);
    }

    /* freebase.mqlReads takes a list of pairs of [fb_key, query] and wraps them in a minimal
       number of HTTP GET requests needed to perform them.  For each query result
       it calls handler(fb_key, result) if the query is successful, and onError(fb_key, response)
       if the mql query fails.  After all of the queries have been handled, it calls onComplete()
    */
    freebase.mqlReads = function(q_pairs, handler, onComplete, onError) {
        if (q_pairs.length === 0){
            onComplete();
            return;
        }
        var keys = $.map(q_pairs, function(q_pair){return q_pair[0]});
        function dispatcher(result) {
            assert(keys.length > 0);
            var i = 0;
            while(i < keys.length) {
                var key = keys[i];
                var value = result[idToQueryName(key)];
                if (!value) {
                    i++;
                    continue;
                }

                //We've handled the ith key, remove it from the list of keys
                keys = removeAt(keys, i);
                if (freebase.isBadOrEmptyResult(value)){
                    if (onError)
                        onError(key, value);
                    else
                        error(value);
                }
                else
                    handler(key, value.result);
            }
            if (keys.length === 0)
                onComplete();
        }
        var encoded_queries = $.each(q_pairs, function(_,q_pair){q_pair[0] = idToQueryName(q_pair[0]);});
        multiQuery(encoded_queries, dispatcher);
    }

    function idToQueryName(id) {
        return id.replace(/\//g,'ZZZZ');
    }

    /* multiQuery takes a list of pairs of [name, query] and breaks them up so that it
       each mql query fits in an HTTP GET request, calling handler on each container
       query result
    */
    var maxURLLength = 3998;
    function multiQuery(queries, handler) {
        var query = {};
        $.each(queries, function(_,qparts) {
            query[qparts[0]] = qparts[1];
        });
        if (queries.length > 1 && getMqlReadURL(query).length > maxURLLength) {
            var splitPoint = queries.length / 2;
            multiQuery(queries.slice(0, splitPoint), handler);
            multiQuery(queries.slice(splitPoint),    handler);
        }
        else
            freebase.mqlRead(query, handler);
    }

    /* Given an id and a callback, immediately calls the callback with the freebase name
      if it has been looked up before.

      If it hasn't, then the callback is called once with the id immediately, and once again
      with the name after it has been looked up.*/
    var nameCache = {};
    freebase.getName = function(id, callback) {
        if (id in nameCache){
            callback(nameCache[id]);
            return;
        }
        callback(id);
        freebase.mqlRead({query:{id:id,name:null}}, function(results) {
            nameCache[id] = (results && results.result && results.result.name) || id;
            callback(nameCache[id]);
        });
    }
    freebase.makeLink = function(id) {
        var simpleEl = node("span",id);
        var link = freebase.link(simpleEl, id);
        freebase.getName(id, function(name) {
            simpleEl.html(name);
        });
        return link;
    }

    var typeMetadata = {};
    freebase.fetchTypeInfo = function(types, onComplete, onError) {
        var q_pairs = [];
        $.each(types, function(_,type) {
            if (!freebase.getTypeMetadata(type))
                return;
            q_pairs.push([type, {query:getQuery(type)}]);
        })

        var errorTypes = [];
        freebase.mqlReads(q_pairs, handler, onCompleteHandler, onErrorHandler);

        function getQuery(type) {
            return {
                id:type,
                type:'/type/type',
                "/freebase/type_hints/included_types":[]
            }
        }

        function handler(type, result) {
            typeMetadata[type] = result;
        }

        function onErrorHandler(type, response) {
            errorTypes.push(type);
        }

        function onCompleteHandler() {
            if (errorTypes.length > 0 && onError){
                onError(errorTypes);
                return;
            }
            onComplete();
        }
    }
    freebase.getTypeMetadata = function(type) {return typeMetadata[type];}

    var propMetadata = {};
    freebase.fetchPropertyInfo = function(properties, onComplete, onError) {
        var q_pairs = [];
        $.each(properties, function(i, mqlProp) {
            $.each(mqlProp.split(":"), function(i, simpleProp) {
                if (simpleProp == "id" || freebase.getPropMetadata(simpleProp))
                    return;
                q_pairs.push([simpleProp, {query: getQuery(simpleProp)}]);
            })
        })

        var errorProps = [];
        freebase.mqlReads(q_pairs, handler, onCompleteHandler, onErrorHandler);

        function getQuery(prop) {
            return {
                "expected_type" : {
                    "extends" : [],
                    "id" : null,
                    "/freebase/type_hints/mediator" : {"optional":true, "value":null}
                },
                "reverse_property" : null,
                "master_property"  : null,
                "type" : "/type/property",
                "name":null,
                "id" : prop
            }
        }

        function handler(mqlProp, result){
            if (result.expected_type.id)
                typesSeen.add(result.expected_type.id)
            result.inverse_property = result.reverse_property || result.master_property;
            propMetadata[mqlProp] = result;
        }

        function onErrorHandler(key, response) {
            errorProps.push(key);
        }

        function onCompleteHandler() {
            if (errorProps.length > 0)
                onError(errorProps);
            else
                onComplete();
        }

    }
    freebase.getPropMetadata = function(prop) {return propMetadata[prop];}

    freebase.isBadOrEmptyResult = function(mqlResult) {
        return mqlResult.code != "/api/status/ok" || mqlResult.result === null;
    }

    freebase.beacon = function(info) {
        var url = "http://www.freebase.com/private/beacon?c=spreadsheetloader" + (info || "");
        $("").appendTo($("body"));
    }

    return freebase;
}());

<commit_msg>Refactored some of freebase.js with suggestions from code review<commit_after>var freebase = (function() {
    var freebase = {};
    var miniTopicFloaterEl = $("#miniTopicFloater");
    freebase.link = function(name, id) {
        var linkVal = node("a", name, {target:'_blank',href:freebase_url + '/view' + id})
        return miniTopicFloater(linkVal, id);

        function miniTopicFloater(element, id) {
            var mouseIsOver = false;
            element.bind("mouseover",function() {
                mouseIsOver = true;
                miniTopicFloaterEl.empty().freebaseMiniTopic(id, function(){
                    if (mouseIsOver)
                        miniTopicFloaterEl.show();
                });
            })
            element.bind("mouseout", function() {
                mouseIsOver = false;
                miniTopicFloaterEl.hide();
            })
            element.mousemove(function(e){
                miniTopicFloaterEl.css({
                    top: (e.pageY + 15) + "px",
                    left: (e.pageX + 15) + "px"
                });
            });
            return element;
        }
    };

    // Simple mql read
    freebase.mqlRead = function mqlRead(envelope, handler) {
        $.getJSON(getMqlReadURL(envelope), null, handler);
    };

    /* Used below, thus the odd style above */
    function getMqlReadURL(envelope) {
        var param = {query:JSON.stringify(envelope)};
        if (!('query' in envelope))
            param = {queries:param.query};
        return freebase_url + "/api/service/mqlread?callback=?&" + $.param(param);
    }

    /* Maps a freebase ID into a valid MQL query id */
    function idToQueryName(id) {
        return id.replace(/\//g,'ZZZZ');
    }

    /* freebase.mqlReads takes a list of pairs of [fb_key, query] and wraps them in a minimal
       number of HTTP GET requests needed to perform them.  For each query result
       it calls handler(fb_key, result) if the query is successful, and onError(fb_key, response)
       if the mql query fails.  After all of the queries have been handled, it calls onComplete()
    */
    var maxURLLength = 2048;
    freebase.mqlReads = function(q_pairs, handler, onComplete, errorHandler) {
        if (q_pairs.length === 0){
            onComplete();
            return;
        }
        var keys = $.map(q_pairs, function(q_pair){return q_pair[0]});
        var encoded_queries = $.each(q_pairs, function(_,q_pair){q_pair[0] = idToQueryName(q_pair[0]);});
        multiQuery(encoded_queries);

        /* multiQuery takes a list of pairs of [name, query] and breaks them up so that it
           each mql query fits in an HTTP GET request, calling handler on each container
           query result
        */
        function multiQuery(queries) {
            var query = {};
            $.each(queries, function(_,qparts) {
                query[qparts[0]] = qparts[1];
            });
            if (queries.length > 1 && getMqlReadURL(query).length > maxURLLength) {
                var splitPoint = queries.length / 2;
                multiQuery(queries.slice(0, splitPoint));
                multiQuery(queries.slice(splitPoint));
            }
            else
                freebase.mqlRead(query, dispatcher);
        }

        /* Takes the result of multiple mql queries all wrapped up together
           and dispatches them to handler if they succeeded, errorHandler
           if they failed, and calls onComplete if all of the keys have
           been handled. */
        function dispatcher(responseGroup) {
            assert(keys.length > 0);
            log(responseGroup);
            var i = 0;
            while(i < keys.length) {
                var key = keys[i];
                var response = responseGroup[idToQueryName(key)];
                if (!response) {
                    i++;
                    continue;
                }

                //We've handled the ith key, remove it from the list of keys
                keys = removeAt(keys, i);
                if (freebase.isBadOrEmptyResult(response)) {
                    if (errorHandler)
                        errorHandler(key, response);
                    else
                        error(value);
                }
                else
                    handler(key, response.result);
            }
            if (keys.length === 0)
                onComplete();
        }
    }

    /* Given an id and a callback, immediately calls the callback with the freebase name
      if it has been looked up before.

      If it hasn't, then the callback is called once with the id immediately, and once again
      with the name after it has been looked up.*/
    var nameCache = {};
    freebase.getName = function(id, callback) {
        if (id in nameCache){
            callback(nameCache[id]);
            return;
        }
        callback(id);
        freebase.mqlRead({query:{id:id,name:null}}, function(results) {
            nameCache[id] = (results && results.result && results.result.name) || id;
            callback(nameCache[id]);
        });
    }
    freebase.makeLink = function(id) {
        var simpleEl = node("span",id);
        var link = freebase.link(simpleEl, id);
        freebase.getName(id, function(name) {
            simpleEl.html(name);
        });
        return link;
    }

    var typeMetadata = {};
    freebase.fetchTypeInfo = function(types, onComplete, onError) {
        var q_pairs = [];
        $.each(types, function(_,type) {
            if (!freebase.getTypeMetadata(type))
                return;
            q_pairs.push([type, {query:getQuery(type)}]);
        })

        var errorTypes = [];
        freebase.mqlReads(q_pairs, handler, onCompleteHandler, onErrorHandler);

        function getQuery(type) {
            return {
                id:type,
                type:'/type/type',
                "/freebase/type_hints/included_types":[]
            }
        }

        function handler(type, result) {
            typeMetadata[type] = result;
        }

        function onErrorHandler(type, response) {
            errorTypes.push(type);
        }

        function onCompleteHandler() {
            if (errorTypes.length > 0 && onError){
                onError(errorTypes);
                return;
            }
            onComplete();
        }
    }
    freebase.getTypeMetadata = function(type) {return typeMetadata[type];}

    var propMetadata = {};
    freebase.fetchPropertyInfo = function(properties, onComplete, onError) {
        var q_pairs = [];
        $.each(properties, function(i, mqlProp) {
            $.each(mqlProp.split(":"), function(i, simpleProp) {
                if (simpleProp == "id" || freebase.getPropMetadata(simpleProp))
                    return;
                q_pairs.push([simpleProp, {query: getQuery(simpleProp)}]);
            })
        })

        var errorProps = [];
        freebase.mqlReads(q_pairs, handler, onCompleteHandler, onErrorHandler);

        function getQuery(prop) {
            return {
                "expected_type" : {
                    "extends" : [],
                    "id" : null,
                    "/freebase/type_hints/mediator" : {"optional":true, "value":null}
                },
                "reverse_property" : null,
                "master_property"  : null,
                "type" : "/type/property",
                "name":null,
                "id" : prop
            }
        }

        function handler(mqlProp, result){
            if (result.expected_type.id)
                typesSeen.add(result.expected_type.id)
            result.inverse_property = result.reverse_property || result.master_property;
            propMetadata[mqlProp] = result;
        }

        function onErrorHandler(key, response) {
            errorProps.push(key);
        }

        function onCompleteHandler() {
            if (errorProps.length > 0)
                onError(errorProps);
            else
                onComplete();
        }

    }
    freebase.getPropMetadata = function(prop) {return propMetadata[prop];}

    freebase.isBadOrEmptyResult = function(mqlResult) {
        return mqlResult.code != "/api/status/ok" || mqlResult.result === null;
    }

    freebase.beacon = function(info) {
        var url = "http://www.freebase.com/private/beacon?c=spreadsheetloader" + (info || "");
        $("").appendTo($("body"));
    }

    return freebase;
}());<|endoftext|>


<commit_before>// CONFIGURE ME!
mainDb = Mongo('127.0.0.1:27017').getDB('lichess');
oauthDb = Mongo('127.0.0.1:27017').getDB('lichess');
studyDb = Mongo('127.0.0.1:27017').getDB('lichess');
puzzleDb = Mongo('127.0.0.1:27017').getDB('puzzler');
// CONFIG END

if (typeof user == 'undefined') throw 'Usage: mongo --eval \'user="username"\' script.js';

user = db.user4.findOne({ _id: user });

if (!user || user.enabled || !user.erasedAt) throw 'Erase with lichess CLI first.';

print(`\n\n Delete user ${user.username} and all references to their username!\n\n`);
sleep(5000);

const userId = user._id;
const tosViolation = user.marks && user.marks.length;

const ghostId = 'ghost';
const newGhostId = () => {
  const idChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const idLength = 8;
  let id = '';
  for (let i = idLength; i > 0; --i) id += idChars[Math.floor(Math.random() * idChars.length)];
  return `!${id}`;
};

const scrub = (collName, inDb) => f => {
  print(`- ${collName}`);
  sleep(200);
  return f((inDb || mainDb)[collName]);
};

const byId = doc => ({ _id: doc._id });
const deleteAllIn = (db, collName, field, value) => scrub(collName, db)(c => c.remove({ [field]: value || userId }));
const deleteAll = (collName, field, value) => deleteAllIn(mainDb, collName, field, value);
const replaceWithGhostId = (collName, field, inDb) =>
  scrub(collName, inDb)(c => c.updateMany({ [field]: userId }, { $set: { [field]: ghostId } }));

// Let us scrub.

deleteAll('activity', '_id', new RegExp(`^${userId}:`));

deleteAll('analysis_requester', '_id');

deleteAll('bookmark', 'u');

deleteAll('challenge', 'challenger.id');
deleteAll('challenge', 'destUser.id');

replaceWithGhostId('clas_clas', 'created.by');
scrub('clas_clas')(c => c.updateMany({ teachers: userId }, { $pull: { teachers: userId } }));

deleteAll('clas_student', 'userId');

deleteAll('coach', '_id');

deleteAll('coach_review', 'userId');
deleteAll('coach_review', 'coachId');

deleteAll('config', '_id');

deleteAll('coordinate_score', '_id');

deleteAll('crosstable2', '_id', new RegExp(`^${userId}/`));

scrub('f_post')(c => c.updateMany({ userId: userId }, { $set: { userId: ghostId, text: '', erasedAt: new Date() } }));

scrub('game5')(c =>
  c.find({ us: userId }, { us: 1, wid: 1 }).forEach(doc => {
    c.update(byId(doc), {
      $set: {
        [`us.${doc.us.indexOf(userId)}`]: ghostId, // replace in player usernames
      },
      ...(doc.wid == userId ? { $unset: { wid: 1 } } : {}), // remove winner username
    });
  })
);

deleteAll('history3', '_id');

deleteAll('image', 'createdBy');

deleteAll('irwin_report', '_id');

deleteAll('learn_progress', '_id');

deleteAll('matchup', '_id', new RegExp(`^${userId}/`));

/*
We decided not to delete PMs out of legit interest of the correspondents
and also to be able to comply with data requests from law enforcement

const msgThreadIds = scrub('msg_thread')(c => {
  const ids = c.distinct('_id', { users: userId });
  c.remove({ users: userId });
  return ids;
});
scrub('msg_msg')(c => msgThreadIds.length && c.remove({ tid: { $in: msgThreadIds } }));
*/

scrub('note')(c => {
  c.remove({ from: userId, mod: { $ne: true } });
  c.remove({ to: userId, mod: { $ne: true } });
});

deleteAll('notify', 'notifies');

replaceWithGhostId('oauth_client', 'author', oauthDb);

deleteAllIn(oauthDb, 'oauth_access_token', 'user_id');

deleteAll('perf_stat', new RegExp(`^${userId}/`));

replaceWithGhostId('plan_charge', 'userId');

deleteAll('plan_patron', '_id');

deleteAll('playban', '_id');

deleteAll('player_assessment', 'userId');

deleteAll('practice_progress', '_id');

deleteAll('pref', '_id');

deleteAll('push_device', 'userId');

scrub('puzzle2_puzzle', puzzleDb)(c => c.updateMany({ users: userId }, { $set: { 'users.$': ghostId } }));

deleteAllIn(puzzleDb, 'puzzle2_round', '_id', new RegExp(`^${userId}:`));

deleteAll('ranking', new RegExp(`^${userId}:`));

deleteAll('relation', 'u1');
deleteAll('relation', 'u2');

scrub('report2')(c => {
  c.find({ 'atoms.by': userId }, { atoms: 1 }).forEach(doc => {
    const newAtoms = doc.atoms.map(a => ({
      ...a,
      by: a.by == userId ? ghostId : a.by,
    }));
    c.update(byId(doc), { $set: { atoms: newAtoms } });
  });
  !tosViolation && c.updateMany({ user: userId }, { $set: { user: ghostId } });
});

if (!tosViolation) deleteAll('security', 'user');

deleteAll('seek', 'user.id');

deleteAll('shutup', '_id');

replaceWithGhostId('simul', 'hostId');
scrub('simul')(c => c.updateMany({ 'pairings.player.user': userId }, { $set: { 'pairings.$.player.user': ghostId } }));

deleteAll('storm_day', '_id', new RegExp(`^${userId}:`));

deleteAll('streamer', '_id');

const studyIds = scrub(
  'study',
  studyDb
)(c => {
  const ids = c.distinct('_id', { ownerId: userId });
  c.remove({ ownerId: userId });
  c.updateMany({ likers: userId }, { $pull: { likers: userId } });
  c.updateMany({ uids: userId }, { $pull: { uids: userId }, $unset: { [`members.${userId}`]: true } });
  return ids;
});

if (studyIds.length) scrub('study_chapter_flat', studyDb)(c => c.remove({ studyId: { $in: studyIds } }));

deleteAllIn(studyDb, 'study_user_topic', '_id');

replaceWithGhostId('swiss', 'winnerId');

const swissIds = scrub('swiss_player')(c => c.distinct('s', { u: userId }));

if (swissIds.length) {
  // here we use a single ghost ID for all swiss players and pairings,
  // because the mapping of swiss player to swiss pairings must be preserved
  const swissGhostId = newGhostId();
  scrub('swiss_player')(c => {
    c.find({ _id: { $in: swissIds.map(s => `${s}:${userId}`) } }).forEach(p => {
      c.remove({ _id: p._id });
      p._id = `${p.s}:${swissGhostId}`;
      p.u = swissGhostId;
      c.insert(p);
    });
  });
  scrub('swiss_pairing')(c => c.updateMany({ s: { $in: swissIds }, p: userId }, { $set: { 'p.$': swissGhostId } }));
}

replaceWithGhostId('team', 'createdBy');
scrub('team')(c => c.updateMany({ leaders: userId }, { $pull: { leaders: userId } }));

deleteAll('team_request', 'user');

deleteAll('team_member', 'user');

replaceWithGhostId('tournament2', 'createdBy');
replaceWithGhostId('tournament2', 'winnerId');

const arenaIds = scrub('tournament_leaderboard')(c => c.distinct('t', { u: userId }));
if (arenaIds.length) {
  // here we use a single ghost ID for all arena players and pairings,
  // because the mapping of arena player to arena pairings must be preserved
  const arenaGhostId = newGhostId();
  scrub('tournament_player')(c =>
    c.updateMany({ tid: { $in: arenaIds }, uid: userId }, { $set: { uid: arenaGhostId } })
  );
  scrub('tournament_pairing')(c =>
    c.updateMany({ tid: { $in: arenaIds }, u: userId }, { $set: { 'u.$': arenaGhostId } })
  );
  deleteAll('tournament_leaderboard', 'u');
}

deleteAll('trophy', 'user');

scrub('user4')(c =>
  c.update(
    { _id: userId },
    // If the user was banned for TOS violations, delete the following fields:
    tosViolation
      ? {
          $unset: {
            profile: 1,
            roles: 1,
            toints: 1,
            time: 1,
            kid: 1,
            lang: 1,
            title: 1,
            plan: 1,
            totp: 1,
            changedCase: 1,
            blind: 1,
            salt: 1,
            bpass: 1,
            mustConfirmEmail: 1,
            colorIt: 1,
          },
        }
      : // Else, delete everything from the user document, with the following exceptions:
        // - _id, as to prevent signing up with the same username again. Usernames must NOT be reused.
        // - prevEmail and createdAt, to prevent mass-creation of accounts reusing the same email address.
        {
          prevEmail: user.prevEmail,
          createdAt: user.createdAt,
        }
  )
);

deleteAll('video_view', 'u');
<commit_msg>configure all connections from outside the script<commit_after>// Usage:
// mongo --eval 'mainDb="localhost/lichess";oauthDb="localhost/lichess";studyDb="localhost/lichess";puzzleDb="localhost/puzzler";user="username"' bin/mongodb/user-gdpr-scrub.js

mainDb = connect(mainDb);
oauthDb = connect(oauthDb);
studyDb = connect(studyDb);
puzzleDb = connect(puzzleDb);

if (typeof user == 'undefined') throw 'Missing user argument';

user = db.user4.findOne({ _id: user });

if (!user || user.enabled || !user.erasedAt) throw 'Erase with lichess CLI first.';

print(`\n\n Delete user ${user.username} and all references to their username!\n\n`);
sleep(5000);

const userId = user._id;
const tosViolation = user.marks && user.marks.length;

const ghostId = 'ghost';
const newGhostId = () => {
  const idChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const idLength = 8;
  let id = '';
  for (let i = idLength; i > 0; --i) id += idChars[Math.floor(Math.random() * idChars.length)];
  return `!${id}`;
};

const scrub = (collName, inDb) => f => {
  print(`- ${collName}`);
  sleep(200);
  return f((inDb || mainDb)[collName]);
};

const byId = doc => ({ _id: doc._id });
const deleteAllIn = (db, collName, field, value) => scrub(collName, db)(c => c.remove({ [field]: value || userId }));
const deleteAll = (collName, field, value) => deleteAllIn(mainDb, collName, field, value);
const replaceWithGhostId = (collName, field, inDb) =>
  scrub(collName, inDb)(c => c.updateMany({ [field]: userId }, { $set: { [field]: ghostId } }));

// Let us scrub.

deleteAll('activity', '_id', new RegExp(`^${userId}:`));

deleteAll('analysis_requester', '_id');

deleteAll('bookmark', 'u');

deleteAll('challenge', 'challenger.id');
deleteAll('challenge', 'destUser.id');

replaceWithGhostId('clas_clas', 'created.by');
scrub('clas_clas')(c => c.updateMany({ teachers: userId }, { $pull: { teachers: userId } }));

deleteAll('clas_student', 'userId');

deleteAll('coach', '_id');

deleteAll('coach_review', 'userId');
deleteAll('coach_review', 'coachId');

deleteAll('config', '_id');

deleteAll('coordinate_score', '_id');

deleteAll('crosstable2', '_id', new RegExp(`^${userId}/`));

scrub('f_post')(c => c.updateMany({ userId: userId }, { $set: { userId: ghostId, text: '', erasedAt: new Date() } }));

scrub('game5')(c =>
  c.find({ us: userId }, { us: 1, wid: 1 }).forEach(doc => {
    c.update(byId(doc), {
      $set: {
        [`us.${doc.us.indexOf(userId)}`]: ghostId, // replace in player usernames
      },
      ...(doc.wid == userId ? { $unset: { wid: 1 } } : {}), // remove winner username
    });
  })
);

deleteAll('history3', '_id');

deleteAll('image', 'createdBy');

deleteAll('irwin_report', '_id');

deleteAll('learn_progress', '_id');

deleteAll('matchup', '_id', new RegExp(`^${userId}/`));

/*
We decided not to delete PMs out of legit interest of the correspondents
and also to be able to comply with data requests from law enforcement

const msgThreadIds = scrub('msg_thread')(c => {
  const ids = c.distinct('_id', { users: userId });
  c.remove({ users: userId });
  return ids;
});
scrub('msg_msg')(c => msgThreadIds.length && c.remove({ tid: { $in: msgThreadIds } }));
*/

scrub('note')(c => {
  c.remove({ from: userId, mod: { $ne: true } });
  c.remove({ to: userId, mod: { $ne: true } });
});

deleteAll('notify', 'notifies');

replaceWithGhostId('oauth_client', 'author', oauthDb);

deleteAllIn(oauthDb, 'oauth_access_token', 'user_id');

deleteAll('perf_stat', new RegExp(`^${userId}/`));

replaceWithGhostId('plan_charge', 'userId');

deleteAll('plan_patron', '_id');

deleteAll('playban', '_id');

deleteAll('player_assessment', 'userId');

deleteAll('practice_progress', '_id');

deleteAll('pref', '_id');

deleteAll('push_device', 'userId');

scrub('puzzle2_puzzle', puzzleDb)(c => c.updateMany({ users: userId }, { $set: { 'users.$': ghostId } }));

deleteAllIn(puzzleDb, 'puzzle2_round', '_id', new RegExp(`^${userId}:`));

deleteAll('ranking', new RegExp(`^${userId}:`));

deleteAll('relation', 'u1');
deleteAll('relation', 'u2');

scrub('report2')(c => {
  c.find({ 'atoms.by': userId }, { atoms: 1 }).forEach(doc => {
    const newAtoms = doc.atoms.map(a => ({
      ...a,
      by: a.by == userId ? ghostId : a.by,
    }));
    c.update(byId(doc), { $set: { atoms: newAtoms } });
  });
  !tosViolation && c.updateMany({ user: userId }, { $set: { user: ghostId } });
});

if (!tosViolation) deleteAll('security', 'user');

deleteAll('seek', 'user.id');

deleteAll('shutup', '_id');

replaceWithGhostId('simul', 'hostId');
scrub('simul')(c => c.updateMany({ 'pairings.player.user': userId }, { $set: { 'pairings.$.player.user': ghostId } }));

deleteAll('storm_day', '_id', new RegExp(`^${userId}:`));

deleteAll('streamer', '_id');

const studyIds = scrub(
  'study',
  studyDb
)(c => {
  const ids = c.distinct('_id', { ownerId: userId });
  c.remove({ ownerId: userId });
  c.updateMany({ likers: userId }, { $pull: { likers: userId } });
  c.updateMany({ uids: userId }, { $pull: { uids: userId }, $unset: { [`members.${userId}`]: true } });
  return ids;
});

if (studyIds.length) scrub('study_chapter_flat', studyDb)(c => c.remove({ studyId: { $in: studyIds } }));

deleteAllIn(studyDb, 'study_user_topic', '_id');

replaceWithGhostId('swiss', 'winnerId');

const swissIds = scrub('swiss_player')(c => c.distinct('s', { u: userId }));

if (swissIds.length) {
  // here we use a single ghost ID for all swiss players and pairings,
  // because the mapping of swiss player to swiss pairings must be preserved
  const swissGhostId = newGhostId();
  scrub('swiss_player')(c => {
    c.find({ _id: { $in: swissIds.map(s => `${s}:${userId}`) } }).forEach(p => {
      c.remove({ _id: p._id });
      p._id = `${p.s}:${swissGhostId}`;
      p.u = swissGhostId;
      c.insert(p);
    });
  });
  scrub('swiss_pairing')(c => c.updateMany({ s: { $in: swissIds }, p: userId }, { $set: { 'p.$': swissGhostId } }));
}

replaceWithGhostId('team', 'createdBy');
scrub('team')(c => c.updateMany({ leaders: userId }, { $pull: { leaders: userId } }));

deleteAll('team_request', 'user');

deleteAll('team_member', 'user');

replaceWithGhostId('tournament2', 'createdBy');
replaceWithGhostId('tournament2', 'winnerId');

const arenaIds = scrub('tournament_leaderboard')(c => c.distinct('t', { u: userId }));
if (arenaIds.length) {
  // here we use a single ghost ID for all arena players and pairings,
  // because the mapping of arena player to arena pairings must be preserved
  const arenaGhostId = newGhostId();
  scrub('tournament_player')(c =>
    c.updateMany({ tid: { $in: arenaIds }, uid: userId }, { $set: { uid: arenaGhostId } })
  );
  scrub('tournament_pairing')(c =>
    c.updateMany({ tid: { $in: arenaIds }, u: userId }, { $set: { 'u.$': arenaGhostId } })
  );
  deleteAll('tournament_leaderboard', 'u');
}

deleteAll('trophy', 'user');

scrub('user4')(c =>
  c.update(
    { _id: userId },
    // If the user was banned for TOS violations, delete the following fields:
    tosViolation
      ? {
          $unset: {
            profile: 1,
            roles: 1,
            toints: 1,
            time: 1,
            kid: 1,
            lang: 1,
            title: 1,
            plan: 1,
            totp: 1,
            changedCase: 1,
            blind: 1,
            salt: 1,
            bpass: 1,
            mustConfirmEmail: 1,
            colorIt: 1,
          },
        }
      : // Else, delete everything from the user document, with the following exceptions:
        // - _id, as to prevent signing up with the same username again. Usernames must NOT be reused.
        // - prevEmail and createdAt, to prevent mass-creation of accounts reusing the same email address.
        {
          prevEmail: user.prevEmail,
          createdAt: user.createdAt,
        }
  )
);

deleteAll('video_view', 'u');
<|endoftext|>


<commit_before>"use strict"
const FirebaseRef = Firebase;

Firebase = {};

class Collection {
  constructor(name, options){
    options = options || {};

    var endpoint = options.endpoint;

    if (!endpoint){
      throw new Meteor.Error('firebase-error', 'no endpoint specified');
    }

    this.ref = new FirebaseRef( UrlUtils.resolve(endpoint, name)  );
  }
};

Firebase.Collection = Collection;
// useful for debug
Firebase._FirebaseRef = FirebaseRef;
<commit_msg>implemented insert method<commit_after>"use strict"
const FirebaseRef = Firebase;

Firebase = {};

class Collection {
  constructor(name, options){
    options = options || {};

    var endpoint = options.endpoint;

    if (!endpoint){
      throw new Meteor.Error('firebase-error', 'no endpoint specified');
    }

    this.ref = new FirebaseRef( UrlUtils.resolve(endpoint, name)  );
  }
  /**
   *@summary Insert a document into a collection. Returns its unique _id;
   */
  insert(doc){
    var newDocRef = this.ref.push(doc);
    return newDocRef.key();
  }
};

Firebase.Collection = Collection;
// useful for debug
Firebase._FirebaseRef = FirebaseRef;
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var SearchResults = require('./SearchResults');
var AddOpenMicForm = require('./AddOpenMicForm');
var {
    StyleSheet,
    Text,
    TextInput,
    View,
    ScrollView,
    TouchableHighlight,
    ActivityIndicatorIOS,
    Image,
    Component
} = React;

function urlForQueryAndPage(key, value) {
    var data = {
        city: value
    };

    var querystring = Object.keys(data)
        .map(key => key + '=' + encodeURIComponent(data[key]))
        .join('&');

    return 'http://localhost:3000/api/openmic/listForCity?' + querystring;
};

class SearchPage extends Component {

    constructor(props) {
        super(props);
        this.state = {
            searchString: 'Denver',
            isLoading: false,
            message: ''
        };
    }

    _handleResponse(openmics) {
        this.setState({isLoading: false});
        if (openmics.length) {
            this.props.navigator.push({
                title: this.capitalize(this.state.searchString),
                component: SearchResults,
                passProps: {openmics: openmics}
            });
        } else {
            this.setState({message: 'Location not recognized or does not have any open mics. Please try again.'});
        }
    }

    _executeQuery(query) {
        this.setState({isLoading: true, message: ''});
        fetch(query)
            .then(response => response.json())
            .then(data => this._handleResponse(data))
            .catch(error => {
                this.setState({
                    isLoading: false,
                    message: 'Something bad happened ' + error
                });
            });
    }

    onSearchPressed() {
        var query = urlForQueryAndPage('place_name', this.state.searchString);
        this._executeQuery(query);
    }

    onAddOpenMicButtonPressed() {
        this.props.navigator.push({
            title: 'Add an Open Mic',
            component: AddOpenMicForm,
            passProps: {}
        });
    }

    onSearchTextChanged(event) {
        this.setState({searchString: event.nativeEvent.text});
    }

    render() {
        var spinner = this.state.isLoading ?
            ( <ActivityIndicatorIOS
                hidden='true'
                size='large'/> ) :
            ( <View/>);

        return (
            <ScrollView>
                <View style={styles.container}>
                <Text style={styles.description}>
                    Find Open Mics in your area!
                </Text>

                <Image source={require('./img/microphone.png')} style={styles.image}/>

                <Text style={styles.description}>
                    Search by city name.
                </Text>
                <View style={styles.flowRight}>
                    <TextInput
                        style={styles.searchInput}
                        placeholder='Search via city name'
                        value={this.state.searchString}
                        onChange={this.onSearchTextChanged.bind(this)}/>
                    <TouchableHighlight style={styles.button}
                                        underlayColor='#99d9f4'
                                        onPress={this.onSearchPressed.bind(this)}>
                        <Text style={styles.buttonText}>Go</Text>
                    </TouchableHighlight>
                </View>
                <TouchableHighlight style={styles.button}
                                    onPress={this.onAddOpenMicButtonPressed.bind(this)}
                                    underlayColor='#99d9f4'>
                    <Text style={styles.buttonText}>Add an Open Mic</Text>
                </TouchableHighlight>
                {spinner}
                <Text style={styles.description}>{this.state.message}</Text>
                </View>
            </ScrollView>
        );
    }

    capitalize(string)
    {
        return string[0].toUpperCase() + string.slice(1);
    }
}

var styles = StyleSheet.create({
    description: {
        marginBottom: 20,
        fontSize: 18,
        textAlign: 'center',
        color: '#656565'
    },
    container: {
        padding: 30,
        //marginTop: 65,
        alignItems: 'center'
    },
    flowRight: {
        flexDirection: 'row',
        alignItems: 'center',
        alignSelf: 'stretch'
    },
    buttonText: {
        fontSize: 18,
        color: 'white',
        alignSelf: 'center'
    },
    button: {
        height: 36,
        flex: 1,
        flexDirection: 'row',
        backgroundColor: '#2196f3',
        borderColor: '#2196f3',
        borderWidth: 1,
        borderRadius: 8,
        marginBottom: 10,
        alignSelf: 'stretch',
        justifyContent: 'center'
    },
    searchInput: {
        height: 36,
        padding: 4,
        marginRight: 5,
        flex: 4,
        fontSize: 18,
        borderWidth: 1,
        borderColor: '#2196f3',
        borderRadius: 8,
        color: '#2196f3'
    },
    image: {
        width: 100,
        height: 200
    }
});

module.exports = SearchPage;<commit_msg>removed unused code<commit_after>'use strict';

var React = require('react-native');
var SearchResults = require('./SearchResults');
var AddOpenMicForm = require('./AddOpenMicForm');
var {
    StyleSheet,
    Text,
    TextInput,
    View,
    ScrollView,
    TouchableHighlight,
    ActivityIndicatorIOS,
    Image,
    Component
} = React;

function urlForQueryAndPage(key, value) {
    var data = {
        city: value
    };

    var querystring = Object.keys(data)
        .map(key => key + '=' + encodeURIComponent(data[key]))
        .join('&');

    return 'http://localhost:3000/api/openmic/listForCity?' + querystring;
};

class SearchPage extends Component {

    constructor(props) {
        super(props);
        this.state = {
            searchString: 'Denver',
            isLoading: false,
            message: ''
        };
    }

    _handleResponse(openmics) {
        this.setState({isLoading: false});
        if (openmics.length) {
            this.props.navigator.push({
                title: this.capitalize(this.state.searchString),
                component: SearchResults,
                passProps: {openmics: openmics}
            });
        } else {
            this.setState({message: 'Location not recognized or does not have any open mics. Please try again.'});
        }
    }

    _executeQuery(query) {
        this.setState({isLoading: true, message: ''});
        fetch(query)
            .then(response => response.json())
            .then(data => this._handleResponse(data))
            .catch(error => {
                this.setState({
                    isLoading: false,
                    message: 'Something bad happened ' + error
                });
            });
    }

    onSearchPressed() {
        var query = urlForQueryAndPage('place_name', this.state.searchString);
        this._executeQuery(query);
    }

    onAddOpenMicButtonPressed() {
        this.props.navigator.push({
            title: 'Add an Open Mic',
            component: AddOpenMicForm,
            passProps: {}
        });
    }

    onSearchTextChanged(event) {
        this.setState({searchString: event.nativeEvent.text});
    }

    render() {
        var spinner = this.state.isLoading ?
            ( <ActivityIndicatorIOS
                hidden='true'
                size='large'/> ) :
            ( <View/>);

        return (
            <ScrollView>
                <View style={styles.container}>
                <Text style={styles.description}>
                    Find Open Mics in your area!
                </Text>

                <Image source={require('./img/microphone.png')} style={styles.image}/>

                <Text style={styles.description}>
                    Search by city name.
                </Text>
                <View style={styles.flowRight}>
                    <TextInput
                        style={styles.searchInput}
                        placeholder='Search via city name'
                        value={this.state.searchString}
                        onChange={this.onSearchTextChanged.bind(this)}/>
                    <TouchableHighlight style={styles.button}
                                        underlayColor='#99d9f4'
                                        onPress={this.onSearchPressed.bind(this)}>
                        <Text style={styles.buttonText}>Go</Text>
                    </TouchableHighlight>
                </View>
                <TouchableHighlight style={styles.button}
                                    onPress={this.onAddOpenMicButtonPressed.bind(this)}
                                    underlayColor='#99d9f4'>
                    <Text style={styles.buttonText}>Add an Open Mic</Text>
                </TouchableHighlight>
                {spinner}
                <Text style={styles.description}>{this.state.message}</Text>
                </View>
            </ScrollView>
        );
    }

    capitalize(string)
    {
        return string[0].toUpperCase() + string.slice(1);
    }
}

var styles = StyleSheet.create({
    description: {
        marginBottom: 20,
        fontSize: 18,
        textAlign: 'center',
        color: '#656565'
    },
    container: {
        padding: 30,
        alignItems: 'center'
    },
    flowRight: {
        flexDirection: 'row',
        alignItems: 'center',
        alignSelf: 'stretch'
    },
    buttonText: {
        fontSize: 18,
        color: 'white',
        alignSelf: 'center'
    },
    button: {
        height: 36,
        flex: 1,
        flexDirection: 'row',
        backgroundColor: '#2196f3',
        borderColor: '#2196f3',
        borderWidth: 1,
        borderRadius: 8,
        marginBottom: 10,
        alignSelf: 'stretch',
        justifyContent: 'center'
    },
    searchInput: {
        height: 36,
        padding: 4,
        marginRight: 5,
        flex: 4,
        fontSize: 18,
        borderWidth: 1,
        borderColor: '#2196f3',
        borderRadius: 8,
        color: '#2196f3'
    },
    image: {
        width: 100,
        height: 200
    }
});

module.exports = SearchPage;<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict'

var connect;
var APP_ID;
var REST_KEY;

if (!(APP_ID = process.env.PARSE_APP_ID) || !(REST_KEY = process.env.PARSE_REST_KEY)) {
	console.error( "\u001b[31mERROR: env vars PARSE_APP_ID or PARSE_REST_KEY not defined.\n'set' or 'export' these vars to your shell to use the demo\u001b[0m" );
	process.exit();
}

console.warn("\u001b[31mStarting sParse Demo Connect Server.\nThis should never, ever be exposed to the wild\u001b[0m");

(connect = require('connect'))(
).use(
	function(req, res, next) {
		res.setHeader( "X-PARSE-APP-ID",   APP_ID );
		res.setHeader( "X-PARSE-REST-KEY", REST_KEY );
		next()
	}
).use( connect.logger( 'dev' )
).use( connect.static( 'demo' )
).use( connect.favicon()
).listen( 3000, function() { console.log("\u001b[32msParse Demo now available at: \u001b[36mhttp://0.0.0.0:3000\u001b[0m"); } );<commit_msg>updated demo-server<commit_after>#!/usr/bin/env node
'use strict'

var connect;
var APP_ID   = process.env.PARSE_APP_ID || null;
var REST_KEY = process.env.PARSE_REST_KEY || null;

if (APP_ID  === null || REST_KEY === null) {
	console.info( "\u001b[36mTip: set' or 'export' PARSE_APP_ID and PARSE_REST_KEY env vars to your shell to automatically set them for the demo App\u001b[0m" );
}

console.warn("\u001b[31mStarting sParse Demo.\nThis service should never, ever be exposed to the wild\u001b[0m");

(connect = require('connect'))(
).use(
	function(req, res, next) {
		if (APP_ID !== null && REST_KEY !== null)
		{
			res.setHeader( "X-PARSE-APP-ID",   APP_ID );
			res.setHeader( "X-PARSE-REST-KEY", REST_KEY );
		}

		next()
	}
).use( connect.logger( 'dev' )
).use( connect.static( 'demo' )
).use( connect.favicon()
).listen( 3000, function() { console.log("\u001b[32msParse Demo now available at: \u001b[36mhttp://0.0.0.0:3000\u001b[0m"); } );<|endoftext|>


<commit_before>var settings_streams = (function () {

var exports = {};

var meta = {
    loaded: false,
};

exports.reset = function () {
    meta.loaded = false;
};

var all_streams = [];

function failed_listing_streams(xhr) {
    ui_report.error(i18n.t("Error listing streams"), xhr, $("#organization-status"));
}

function populate_streams(streams_data) {
    var streams_table = $("#admin_streams_table").expectOne();
    all_streams = streams_data;

    list_render(streams_table, all_streams.streams, {
        name: "admin_streams_list",
        modifier: function (item) {
            return templates.render("admin_streams_list", { stream: item });
        },
        filter: {
            element: streams_table.closest(".settings-section").find(".search"),
            callback: function (item, value) {
                return item.name.toLowerCase().indexOf(value) >= 0;
            },
        },
    }).init();

    loading.destroy_indicator($('#admin_page_streams_loading_indicator'));
}

exports.build_default_stream_table = function (streams_data) {
    var self = {};

    self.row_dict = new Dict();

    var table = $("#admin_default_streams_table").expectOne();

    list_render(table, streams_data, {
        name: "default_streams_list",
        modifier: function (item) {
            var row = $(templates.render("admin_default_streams_list", { stream: item, can_modify: page_params.is_admin }));
            self.row_dict.set(item.stream_id, row);
            return row;
        },
        filter: {
            element: table.closest(".settings-section").find(".search"),
            callback: function (item, value) {
                return item.name.toLowerCase().indexOf(value) >= 0;
            },
        },
    }).init();

    loading.destroy_indicator($('#admin_page_default_streams_loading_indicator'));

    self.remove = function (stream_id) {
        if (self.row_dict.has(stream_id)) {
            var row = self.row_dict.get(stream_id);
            row.remove();
        }
    };

    return self;
};

var default_stream_table;

exports.remove_default_stream = function (stream_id) {
    if (default_stream_table) {
        default_stream_table.remove(stream_id);
    }
};

exports.update_default_streams_table = function () {
    if (/#*organization/.test(window.location.hash) ||
        /#*settings/.test(window.location.hash)) {
        $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove();
        default_stream_table = exports.build_default_stream_table(
            page_params.realm_default_streams);
    }
};

function make_stream_default(stream_name) {
    var data = {
        stream_name: stream_name,
    };
    var default_stream_status = $("#admin-default-stream-status");
    default_stream_status.hide();

    channel.post({
        url: '/json/default_streams',
        data: data,
        error: function (xhr) {
            if (xhr.status.toString().charAt(0) === "4") {
                ui_report.error(i18n.t("Failed"), xhr, default_stream_status);
            } else {
                ui_report.error(i18n.t("Failed"), default_stream_status);
            }
            default_stream_status.show();
        },
    });
}

exports.set_up = function () {
    loading.make_indicator($('#admin_page_streams_loading_indicator'));

    // Populate streams table
    channel.get({
        url:      '/json/streams?include_public=true&include_subscribed=true&include_default=true',
        timeout:  10*1000,
        idempotent: true,
        success: exports.on_load_success,
        error: failed_listing_streams,
    });
};

exports.on_load_success = function (streams_data) {
    meta.loaded = true;

    populate_streams(streams_data);

    exports.update_default_streams_table();

    $(".admin_stream_table").on("click", ".deactivate", function (e) {
        e.preventDefault();
        e.stopPropagation();

        $(".active_stream_row").removeClass("active_stream_row");
        var row = $(e.target).closest(".stream_row");
        row.addClass("active_stream_row");

        var stream_name = row.find('.stream_name').text();

        $("#deactivation_stream_modal .stream_name").text(stream_name);
        $("#deactivation_stream_modal").modal("show");
    });

    $('.create_default_stream').keypress(function (e) {
        if (e.which === 13) {
            e.preventDefault();
            e.stopPropagation();
            var default_stream_input = $(".create_default_stream");
            make_stream_default(default_stream_input.val());
            default_stream_input[0].value = "";
        }
    });

    $('.create_default_stream').typeahead({
        items: 5,
        fixed: true,
        source: function () {
            return stream_data.get_non_default_stream_names();
        },
        highlighter: function (item) {
            return typeahead_helper.render_typeahead_item({ primary: item });
        },
        updater: function (stream_name) {
            make_stream_default(stream_name);
        },
    });

    $(".default-stream-form").on("click", "#do_submit_stream", function (e) {
        e.preventDefault();
        e.stopPropagation();
        var default_stream_input = $(".create_default_stream");
        make_stream_default(default_stream_input.val());
        // Clear value inside input box
        default_stream_input[0].value = "";
    });

    $("#do_deactivate_stream_button").click(function () {
        if ($("#deactivation_stream_modal .stream_name").text() !== $(".active_stream_row").find('.stream_name').text()) {
            blueslip.error("Stream deactivation canceled due to non-matching fields.");
            ui_report.message("Deactivation encountered an error. Please reload and try again.",
               $("#home-error"), 'alert-error');
        }
        $("#deactivation_stream_modal").modal("hide");
        $(".active_stream_row button").prop("disabled", true).text(i18n.t("Working…"));
        var stream_name = $(".active_stream_row").find('.stream_name').text();
        var stream_id = stream_data.get_sub(stream_name).stream_id;
        channel.del({
            url: '/json/streams/' + stream_id,
            error: function (xhr) {
                if (xhr.status.toString().charAt(0) === "4") {
                    $(".active_stream_row button").closest("td").html(
                        $("<p>").addClass("text-error").text(JSON.parse(xhr.responseText).msg)
                    );
                } else {
                    $(".active_stream_row button").text(i18n.t("Failed!"));
                }
            },
            success: function () {
                var row = $(".active_stream_row");
                row.remove();
            },
        });
    });

};

return exports;
}());

if (typeof module !== 'undefined') {
    module.exports = settings_streams;
}
<commit_msg>stream_settings: Remove all_streams variable.<commit_after>var settings_streams = (function () {

var exports = {};

var meta = {
    loaded: false,
};

exports.reset = function () {
    meta.loaded = false;
};

function failed_listing_streams(xhr) {
    ui_report.error(i18n.t("Error listing streams"), xhr, $("#organization-status"));
}

function populate_streams(streams_data) {
    var streams_table = $("#admin_streams_table").expectOne();

    list_render(streams_table, streams_data.streams, {
        name: "admin_streams_list",
        modifier: function (item) {
            return templates.render("admin_streams_list", { stream: item });
        },
        filter: {
            element: streams_table.closest(".settings-section").find(".search"),
            callback: function (item, value) {
                return item.name.toLowerCase().indexOf(value) >= 0;
            },
        },
    }).init();

    loading.destroy_indicator($('#admin_page_streams_loading_indicator'));
}

exports.build_default_stream_table = function (streams_data) {
    var self = {};

    self.row_dict = new Dict();

    var table = $("#admin_default_streams_table").expectOne();

    list_render(table, streams_data, {
        name: "default_streams_list",
        modifier: function (item) {
            var row = $(templates.render("admin_default_streams_list", { stream: item, can_modify: page_params.is_admin }));
            self.row_dict.set(item.stream_id, row);
            return row;
        },
        filter: {
            element: table.closest(".settings-section").find(".search"),
            callback: function (item, value) {
                return item.name.toLowerCase().indexOf(value) >= 0;
            },
        },
    }).init();

    loading.destroy_indicator($('#admin_page_default_streams_loading_indicator'));

    self.remove = function (stream_id) {
        if (self.row_dict.has(stream_id)) {
            var row = self.row_dict.get(stream_id);
            row.remove();
        }
    };

    return self;
};

var default_stream_table;

exports.remove_default_stream = function (stream_id) {
    if (default_stream_table) {
        default_stream_table.remove(stream_id);
    }
};

exports.update_default_streams_table = function () {
    if (/#*organization/.test(window.location.hash) ||
        /#*settings/.test(window.location.hash)) {
        $("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove();
        default_stream_table = exports.build_default_stream_table(
            page_params.realm_default_streams);
    }
};

function make_stream_default(stream_name) {
    var data = {
        stream_name: stream_name,
    };
    var default_stream_status = $("#admin-default-stream-status");
    default_stream_status.hide();

    channel.post({
        url: '/json/default_streams',
        data: data,
        error: function (xhr) {
            if (xhr.status.toString().charAt(0) === "4") {
                ui_report.error(i18n.t("Failed"), xhr, default_stream_status);
            } else {
                ui_report.error(i18n.t("Failed"), default_stream_status);
            }
            default_stream_status.show();
        },
    });
}

exports.set_up = function () {
    loading.make_indicator($('#admin_page_streams_loading_indicator'));

    // Populate streams table
    channel.get({
        url:      '/json/streams?include_public=true&include_subscribed=true&include_default=true',
        timeout:  10*1000,
        idempotent: true,
        success: exports.on_load_success,
        error: failed_listing_streams,
    });
};

exports.on_load_success = function (streams_data) {
    meta.loaded = true;

    populate_streams(streams_data);

    exports.update_default_streams_table();

    $(".admin_stream_table").on("click", ".deactivate", function (e) {
        e.preventDefault();
        e.stopPropagation();

        $(".active_stream_row").removeClass("active_stream_row");
        var row = $(e.target).closest(".stream_row");
        row.addClass("active_stream_row");

        var stream_name = row.find('.stream_name').text();

        $("#deactivation_stream_modal .stream_name").text(stream_name);
        $("#deactivation_stream_modal").modal("show");
    });

    $('.create_default_stream').keypress(function (e) {
        if (e.which === 13) {
            e.preventDefault();
            e.stopPropagation();
            var default_stream_input = $(".create_default_stream");
            make_stream_default(default_stream_input.val());
            default_stream_input[0].value = "";
        }
    });

    $('.create_default_stream').typeahead({
        items: 5,
        fixed: true,
        source: function () {
            return stream_data.get_non_default_stream_names();
        },
        highlighter: function (item) {
            return typeahead_helper.render_typeahead_item({ primary: item });
        },
        updater: function (stream_name) {
            make_stream_default(stream_name);
        },
    });

    $(".default-stream-form").on("click", "#do_submit_stream", function (e) {
        e.preventDefault();
        e.stopPropagation();
        var default_stream_input = $(".create_default_stream");
        make_stream_default(default_stream_input.val());
        // Clear value inside input box
        default_stream_input[0].value = "";
    });

    $("#do_deactivate_stream_button").click(function () {
        if ($("#deactivation_stream_modal .stream_name").text() !== $(".active_stream_row").find('.stream_name').text()) {
            blueslip.error("Stream deactivation canceled due to non-matching fields.");
            ui_report.message("Deactivation encountered an error. Please reload and try again.",
               $("#home-error"), 'alert-error');
        }
        $("#deactivation_stream_modal").modal("hide");
        $(".active_stream_row button").prop("disabled", true).text(i18n.t("Working…"));
        var stream_name = $(".active_stream_row").find('.stream_name').text();
        var stream_id = stream_data.get_sub(stream_name).stream_id;
        channel.del({
            url: '/json/streams/' + stream_id,
            error: function (xhr) {
                if (xhr.status.toString().charAt(0) === "4") {
                    $(".active_stream_row button").closest("td").html(
                        $("<p>").addClass("text-error").text(JSON.parse(xhr.responseText).msg)
                    );
                } else {
                    $(".active_stream_row button").text(i18n.t("Failed!"));
                }
            },
            success: function () {
                var row = $(".active_stream_row");
                row.remove();
            },
        });
    });

};

return exports;
}());

if (typeof module !== 'undefined') {
    module.exports = settings_streams;
}
<|endoftext|>


<commit_before>'use strict'

var memoize = require('memoizee')

var formatData = require('./format')
var aton4 = require('./aton4')

var GEOIP_ROOT = 'QmQQ3BUpPjgYiTdhp4H9YWSCtoFXs8t91njhpvXNNLd3yB'

var memoized_lookup

function _lookup (ipfs, hash, lookfor, cb) {
  ipfs.object.get(hash, function (err, res) {
    if (err) {
      cb(err, null)
    } else {
      var obj = JSON.parse(res.Data)

      var child = 0
      if (obj.type === 'Node') {
        while (obj.mins[child] &&
               obj.mins[child] <= lookfor) {
          child++
        }
        return memoized_lookup(ipfs, res.Links[child - 1].Hash, lookfor, cb)
      } else if (obj.type === 'Leaf') {
        while (obj.data[child] &&
               obj.data[child].min <= lookfor) {
          child++
        }

        if (obj.data[child - 1].data) {
          cb(null, formatData(obj.data[child - 1].data))
        } else {
          cb('Unmapped range', null)
        }
      }
    }
  })
}

memoized_lookup = memoize(_lookup, {async: true})

function lookup (ipfs, ip, cb) {
  memoized_lookup(ipfs, GEOIP_ROOT, aton4(ip), cb)
}

function lookup_root (ipfs, hash, ip, cb) {
  memoized_lookup(ipfs, hash, aton4(ip), cb)
}

module.exports = {
  lookup: lookup,
  lookup_root: lookup_root,
  _lookup: memoized_lookup
}
<commit_msg>Safe JSON.parse call<commit_after>'use strict'

var memoize = require('memoizee')

var formatData = require('./format')
var aton4 = require('./aton4')

var GEOIP_ROOT = 'QmQQ3BUpPjgYiTdhp4H9YWSCtoFXs8t91njhpvXNNLd3yB'

var memoized_lookup

function _lookup (ipfs, hash, lookfor, cb) {
  ipfs.object.get(hash, function (err, res) {
    if (err) {
      return cb(err, null)
    }

    try {
      var obj = JSON.parse(res.Data)
    } catch (err) {
      return cb(err, null)
    }

    var child = 0
    if (obj.type === 'Node') {
      while (obj.mins[child] &&
             obj.mins[child] <= lookfor) {
        child++
      }
      return memoized_lookup(ipfs, res.Links[child - 1].Hash, lookfor, cb)
    } else if (obj.type === 'Leaf') {
      while (obj.data[child] &&
             obj.data[child].min <= lookfor) {
        child++
      }

      if (obj.data[child - 1].data) {
        cb(null, formatData(obj.data[child - 1].data))
      } else {
        cb('Unmapped range', null)
      }
    }
  })
}

memoized_lookup = memoize(_lookup, {async: true})

function lookup (ipfs, ip, cb) {
  memoized_lookup(ipfs, GEOIP_ROOT, aton4(ip), cb)
}

function lookup_root (ipfs, hash, ip, cb) {
  memoized_lookup(ipfs, hash, aton4(ip), cb)
}

module.exports = {
  lookup: lookup,
  lookup_root: lookup_root,
  _lookup: memoized_lookup
}
<|endoftext|>


<commit_before>CRM.$(function($) {

  var contractStatuses = CRM.vars['de.systopia.contract'].contractStatuses;

  // # Link to membership create should be replaced with contract create #
  $('a[href="/civicrm/contact/view/membership?reset=1&action=add&cid=' + CRM.vars['de.systopia.contract'].cid + '&context=membership"]')
  .attr("href", "/civicrm/contract/create?cid=" + CRM.vars['de.systopia.contract'].cid);

  // # Membership rows should be decorated with more information about the contract #

  // Decorate each row on initial load
  $( "#memberships tr.crm-membership" ).each(decorateRow);

  // Set modification edit activities to open in a pop up
  $(document).on( 'click', '.edit-activity', CRM.popup);

  // When a pop up is closed, update the contract status and decorate the row
  $(document).on( "crmPopupFormSuccess", '.edit-activity', function(){
    row = $(this).parent().parent().parent().parent().parent().parent().parent().prev();
    console.log(row);
    id = getIdFromRow(row);
    table = $(row).parent();
    reviewPane = table.find(".crm-membership-review_"+ id)[0];
    reviewLink = table.find("#crm-membership_"+ id + ' .review-link')[0];
    $(reviewPane).find('td').load(reviewLink.href);

    CRM.api3('Contract', 'get_open_modification_counts', {
      "id": id
    }).done(function(result) {
      contractStatuses[id] = result;
      table = $(row).parent();
      reviewPane = table.find(".crm-membership-review_"+ id)[0];
      $(reviewPane).find('td').load(reviewLink.href);

    });
  });

  // Clicking on show review opens up a review pane under the contract if not already open
  $(document).on( "click", ".review-link", function(e) {

    e.preventDefault();
    var row = $(this).parent().parent();
    id = getIdFromRow(row);
    table = $(row).parent();

    reviewPane = table.find(".crm-membership-review_"+ id)[0];
    reviewLink = table.find("#crm-membership_"+ id + ' .review-link')[0];

    if($(reviewPane).is(":visible")){
      $(reviewPane).hide();
      $(reviewLink).html(getReviewLinkText(id));
    }else{
      $(reviewPane).find('td').load(reviewLink.href, function(){
        $(reviewPane).show();
        $(reviewLink).html('(close)');
      });
    }

    // Prevent the default link action

    // console.log(reviewPane);
    // reviewPane.each().remove();
  });

  // Clicking on hide review closes the review pane
  $(document).on( "click", ".hide-review", function() {
    var review = $(this).parent().parent();
    $(review).remove();
  });

  function decorateRow(){
    console.log('called decorateRow');
    // get the status
    id = getIdFromRow(this);
    var contractStatus = contractStatuses[id];

    // Add a needs review
    addReviewHtml.call(this);

    if(contractStatus.needs_review > 0){
      $(this).addClass('needs-review');
    }else{
      $(this).removeClass('needs-review');
    }

    if(contractStatus.scheduled > 0){
      $(this).addClass('scheduled');
    }else{
      $(this).removeClass('scheduled');
    }
  }

  function getIdFromRow(row){
    var elementId = $(row).attr('id');
    return elementId.substr(elementId.indexOf("_") + 1);
  }

  function addReviewHtml(){

    id = getIdFromRow(this);

    // Add text to the membership status field if it is not there already
    if($( this ).find('td.crm-membership-status .review-link').length == 0){
      console.log('adding the review row');
      $( this ).find('td.crm-membership-status').append(
        " " + getReviewLinkText(id) + ""
      );
    }

    if($( this ).parent().find('tr.crm-membership-review_' + id).length == 0){
      $( this ).after("

");
    }
    $( this ).parent().find('tr.crm-membership-review_' + id).hide();

  }

  function getReviewLinkText(id){
    if(contractStatuses[id].needs_review > 0){
      text = '(needs review)';
    }else if(contractStatuses[id].scheduled > 0) {
      text = '(scheduled modifications)';
    } else {
      text = '(view modifications)';
    }
    return text;
  }

});
<commit_msg>refactor review.js. ensure that listeners are only added once<commit_after>CRM.$(function($) {

  var contractStatuses = CRM.vars['de.systopia.contract'].contractStatuses;

  // # Link to membership create should be replaced with contract create #
  $('a[href="/civicrm/contact/view/membership?reset=1&action=add&cid=' + CRM.vars['de.systopia.contract'].cid + '&context=membership"]')
  .attr("href", "/civicrm/contract/create?cid=" + CRM.vars['de.systopia.contract'].cid);

  // Add a membership-review tr with appropriate colspan under each row to
  // receive the contract history
  $( "#memberships tr.crm-membership, #inactive-memberships tr.crm-membership" ).each( function(){
    var elementId = $(this).attr('id');
    var membershipId = elementId.substr(elementId.indexOf("_") + 1);
    var link = " " + getReviewLinkText(membershipId) + "";
    $(this).after("

");
    $(this).find('td.crm-membership-status').append(link);
    decorateRow(membershipId);
  });

  // hide the .membership-review tr by default
  $( "tr.crm-membership-review" ).hide();

  function getReviewLinkText(membershipId){
    if(contractStatuses[membershipId].needs_review > 0){
      return 'needs review';
    }else if(contractStatuses[membershipId].scheduled > 0) {
      return 'scheduled modifications';
    }
    return 'review';
  }

  function decorateRow(membershipId){
    var contractStatus = contractStatuses[membershipId];
    var membershipRow = $(document).find('#crm-membership_' + membershipId);

    if(contractStatus.needs_review > 0){
      membershipRow.addClass('needs-review');
    }else{
      membershipRow.removeClass('needs-review');
    }

    if(contractStatus.scheduled > 0){
      membershipRow.addClass('scheduled');
    }else{
      membershipRow.removeClass('scheduled');
    }
  }

  function toggleReviewPane(membershipId){
    console.log('toggle time');
    var reviewRow = $(document).find('#crm-membership-review_' + membershipId);
    var reviewLink = $(document).find('#crm-membership-review-link_' + membershipId);
    if(reviewRow.is(":visible")){
      reviewRow.hide();
      reviewLink.html(getReviewLinkText(membershipId));
    }else{
      reviewRow.find('td').load('/civicrm/contract/review?reset=&snippet=1&id=' + membershipId, function(){
        reviewRow.show();
        reviewLink.html('hide');
      });
    }
  }

  function updateReviewPane(membershipId){
    var reviewRow = $(document).find('#crm-membership-review_' + membershipId);
    reviewRow.find('td').load('/civicrm/contract/review?reset=&snippet=1&id=' + membershipId);
  }

  function updateMembershipRow(membershipId){
    CRM.api3('Contract', 'get_open_modification_counts', {
      "id": membershipId
    }).done(function(result) {
      contractStatuses[membershipId] = result;
      decorateRow(membershipId);
    });
  }

  // We have to ensure the listeners are only added once (this seems like a
  // fairly mad way to do that but anyhow...)

  if(CRM.vars['de.systopia.contract'].listenersLoaded !== true){

    // Clicking on the toggle-review link toggles the membership-review tr
    $(document).on( 'click', '.toggle-review', function(e){
      e.preventDefault();
      var elementId = $(this).attr('id');
      var membershipId = elementId.substr(elementId.indexOf("_") + 1);
      toggleReviewPane(membershipId);
    });

    // Modification edit activities open in a pop up
    $(document).on( 'click', '.edit-activity', CRM.popup);

    // When modification edit activity pop ups are closed, update the appropriate
    // membership review pane and membership row
    $(document).on( 'crmPopupFormSuccess', '.edit-activity', function(){
      var elementId = $(this).parents('.crm-membership-review').attr('id');
      var membershipId = elementId.substr(elementId.indexOf("_") + 1);
      updateReviewPane(membershipId);
      updateMembershipRow(membershipId);
    });

    $(document).on( 'crmPopupFormSuccess', '.action-item', function(){
      var elementId = $(this).parents('.crm-membership').attr('id');
      var membershipId = elementId.substr(elementId.indexOf("_") + 1);
      console.log(membershipId);
    });

    CRM.vars['de.systopia.contract'].listenersLoaded = true;
  }
});
<|endoftext|>


<commit_before>(function() {
	IssueTrackingSystem.controller('Login', ['$scope', 'requester', function ($scope, requester) {

		$scope.login = function login() {
			requester.loginUser($scope.username, $scope.password);
		};

	}]);
})();<commit_msg>add logic in function login<commit_after>(function() {
	IssueTrackingSystem.controller('Login', ['$scope', '$sessionStorage', '$http', '$q', 'BASEURL',
			function ($scope, $sessionStorage, $http, $q, BASEURL) {
		$scope.login = function login() {
			var deferred = $q.defer();
			$http({
				method: 'POST',
				url: BASEURL + 'users/login',
				data: "username=" + $scope.username + "&password=" + $scope.password,
				headers: {'Content-Type': 'application/x-www-form-urlencoded'}
			}).then(function success(response) {
				deferred.resolve(response.data);
				console.log(response);
				console.log($sessionStorage);
				$sessionStorage.userName = response.data.userName;
				$sessionStorage.userAccessToken = response.data.access_token;
			}, function error(error) {
				console.log(error);
				console.log($sessionStorage);
			});

			return deferred.promise;
		};

	}]);
})();<|endoftext|>