<commit_before>// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"use strict";

global.Proxy = new $Object();

var $Proxy = global.Proxy

function ProxyCreate(handler, proto) {
  if (!IS_SPEC_OBJECT(handler))
    throw MakeTypeError("handler_non_object", ["create"])
  if (IS_UNDEFINED(proto))
    proto = null
  else if (!(IS_SPEC_OBJECT(proto) || proto === null))
    throw MakeTypeError("proto_non_object", ["create"])
  return %CreateJSProxy(handler, proto)
}

function ProxyCreateFunction(handler, callTrap, constructTrap) {
  if (!IS_SPEC_OBJECT(handler))
    throw MakeTypeError("handler_non_object", ["create"])
  if (!IS_SPEC_FUNCTION(callTrap))
    throw MakeTypeError("trap_function_expected", ["createFunction", "call"])
  if (IS_UNDEFINED(constructTrap)) {
    constructTrap = DerivedConstructTrap(callTrap)
  } else if (IS_SPEC_FUNCTION(constructTrap)) {
    // Make sure the trap receives 'undefined' as this.
    var construct = constructTrap
    constructTrap = function() {
      return %Apply(construct, void 0, arguments, 0, %_ArgumentsLength());
    }
  } else {
    throw MakeTypeError("trap_function_expected",
                        ["createFunction", "construct"])
  }
  return %CreateJSFunctionProxy(
    handler, callTrap, constructTrap, $Function.prototype)
}

%InstallFunctions($Proxy, DONT_ENUM, [
  "create", ProxyCreate,
  "createFunction", ProxyCreateFunction
])

////////////////////////////////////////////////////////////////////////////////
// Builtins
////////////////////////////////////////////////////////////////////////////////

function DerivedConstructTrap(callTrap) {
  return function() {
    var proto = this.prototype
    if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
    var obj = new $Object()
    obj.__proto__ = proto
    var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength());
    return IS_SPEC_OBJECT(result) ? result : obj
  }
}

function DelegateCallAndConstruct(callTrap, constructTrap) {
  return function() {
    return %Apply(%_IsConstructCall() ? constructTrap : callTrap,
                  this, arguments, 0, %_ArgumentsLength())
  }
}

function DerivedGetTrap(receiver, name) {
  var desc = this.getPropertyDescriptor(name)
  if (IS_UNDEFINED(desc)) { return desc }
  if ('value' in desc) {
    return desc.value
  } else {
    if (IS_UNDEFINED(desc.get)) { return desc.get }
    // The proposal says: desc.get.call(receiver)
    return %_CallFunction(receiver, desc.get)
  }
}

function DerivedSetTrap(receiver, name, val) {
  var desc = this.getOwnPropertyDescriptor(name)
  if (desc) {
    if ('writable' in desc) {
      if (desc.writable) {
        desc.value = val
        this.defineProperty(name, desc)
        return true
      } else {
        return false
      }
    } else { // accessor
      if (desc.set) {
        // The proposal says: desc.set.call(receiver, val)
        %_CallFunction(receiver, val, desc.set)
        return true
      } else {
        return false
      }
    }
  }
  desc = this.getPropertyDescriptor(name)
  if (desc) {
    if ('writable' in desc) {
      if (desc.writable) {
        // fall through
      } else {
        return false
      }
    } else { // accessor
      if (desc.set) {
        // The proposal says: desc.set.call(receiver, val)
        %_CallFunction(receiver, val, desc.set)
        return true
      } else {
        return false
      }
    }
  }
  this.defineProperty(name, {
    value: val,
    writable: true,
    enumerable: true,
    configurable: true});
  return true;
}

function DerivedHasTrap(name) {
  return !!this.getPropertyDescriptor(name)
}

function DerivedHasOwnTrap(name) {
  return !!this.getOwnPropertyDescriptor(name)
}

function DerivedKeysTrap() {
  var names = this.getOwnPropertyNames()
  var enumerableNames = []
  for (var i = 0, count = 0; i < names.length; ++i) {
    var name = names[i]
    var desc = this.getOwnPropertyDescriptor(TO_STRING_INLINE(name))
    if (!IS_UNDEFINED(desc) && desc.enumerable) {
      enumerableNames[count++] = names[i]
    }
  }
  return enumerableNames
}

function DerivedEnumerateTrap() {
  var names = this.getPropertyNames()
  var enumerableNames = []
  for (var i = 0, count = 0; i < names.length; ++i) {
    var name = names[i]
    var desc = this.getPropertyDescriptor(TO_STRING_INLINE(name))
    if (!IS_UNDEFINED(desc) && desc.enumerable) {
      enumerableNames[count++] = names[i]
    }
  }
  return enumerableNames
}

function ProxyEnumerate(proxy) {
  var handler = %GetHandler(proxy)
  if (IS_UNDEFINED(handler.enumerate)) {
    return %Apply(DerivedEnumerateTrap, handler, [], 0, 0)
  } else {
    return ToStringArray(handler.enumerate(), "enumerate")
  }
}
<commit_msg>Set up Proxy methods the proper way.<commit_after>// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"use strict";

global.Proxy = new $Object();

var $Proxy = global.Proxy

function ProxyCreate(handler, proto) {
  if (!IS_SPEC_OBJECT(handler))
    throw MakeTypeError("handler_non_object", ["create"])
  if (IS_UNDEFINED(proto))
    proto = null
  else if (!(IS_SPEC_OBJECT(proto) || proto === null))
    throw MakeTypeError("proto_non_object", ["create"])
  return %CreateJSProxy(handler, proto)
}

function ProxyCreateFunction(handler, callTrap, constructTrap) {
  if (!IS_SPEC_OBJECT(handler))
    throw MakeTypeError("handler_non_object", ["create"])
  if (!IS_SPEC_FUNCTION(callTrap))
    throw MakeTypeError("trap_function_expected", ["createFunction", "call"])
  if (IS_UNDEFINED(constructTrap)) {
    constructTrap = DerivedConstructTrap(callTrap)
  } else if (IS_SPEC_FUNCTION(constructTrap)) {
    // Make sure the trap receives 'undefined' as this.
    var construct = constructTrap
    constructTrap = function() {
      return %Apply(construct, void 0, arguments, 0, %_ArgumentsLength());
    }
  } else {
    throw MakeTypeError("trap_function_expected",
                        ["createFunction", "construct"])
  }
  return %CreateJSFunctionProxy(
    handler, callTrap, constructTrap, $Function.prototype)
}

%CheckIsBootstrapping()
InstallFunctions($Proxy, DONT_ENUM, [
  "create", ProxyCreate,
  "createFunction", ProxyCreateFunction
])

////////////////////////////////////////////////////////////////////////////////
// Builtins
////////////////////////////////////////////////////////////////////////////////

function DerivedConstructTrap(callTrap) {
  return function() {
    var proto = this.prototype
    if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
    var obj = new $Object()
    obj.__proto__ = proto
    var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength());
    return IS_SPEC_OBJECT(result) ? result : obj
  }
}

function DelegateCallAndConstruct(callTrap, constructTrap) {
  return function() {
    return %Apply(%_IsConstructCall() ? constructTrap : callTrap,
                  this, arguments, 0, %_ArgumentsLength())
  }
}

function DerivedGetTrap(receiver, name) {
  var desc = this.getPropertyDescriptor(name)
  if (IS_UNDEFINED(desc)) { return desc }
  if ('value' in desc) {
    return desc.value
  } else {
    if (IS_UNDEFINED(desc.get)) { return desc.get }
    // The proposal says: desc.get.call(receiver)
    return %_CallFunction(receiver, desc.get)
  }
}

function DerivedSetTrap(receiver, name, val) {
  var desc = this.getOwnPropertyDescriptor(name)
  if (desc) {
    if ('writable' in desc) {
      if (desc.writable) {
        desc.value = val
        this.defineProperty(name, desc)
        return true
      } else {
        return false
      }
    } else { // accessor
      if (desc.set) {
        // The proposal says: desc.set.call(receiver, val)
        %_CallFunction(receiver, val, desc.set)
        return true
      } else {
        return false
      }
    }
  }
  desc = this.getPropertyDescriptor(name)
  if (desc) {
    if ('writable' in desc) {
      if (desc.writable) {
        // fall through
      } else {
        return false
      }
    } else { // accessor
      if (desc.set) {
        // The proposal says: desc.set.call(receiver, val)
        %_CallFunction(receiver, val, desc.set)
        return true
      } else {
        return false
      }
    }
  }
  this.defineProperty(name, {
    value: val,
    writable: true,
    enumerable: true,
    configurable: true});
  return true;
}

function DerivedHasTrap(name) {
  return !!this.getPropertyDescriptor(name)
}

function DerivedHasOwnTrap(name) {
  return !!this.getOwnPropertyDescriptor(name)
}

function DerivedKeysTrap() {
  var names = this.getOwnPropertyNames()
  var enumerableNames = []
  for (var i = 0, count = 0; i < names.length; ++i) {
    var name = names[i]
    var desc = this.getOwnPropertyDescriptor(TO_STRING_INLINE(name))
    if (!IS_UNDEFINED(desc) && desc.enumerable) {
      enumerableNames[count++] = names[i]
    }
  }
  return enumerableNames
}

function DerivedEnumerateTrap() {
  var names = this.getPropertyNames()
  var enumerableNames = []
  for (var i = 0, count = 0; i < names.length; ++i) {
    var name = names[i]
    var desc = this.getPropertyDescriptor(TO_STRING_INLINE(name))
    if (!IS_UNDEFINED(desc) && desc.enumerable) {
      enumerableNames[count++] = names[i]
    }
  }
  return enumerableNames
}

function ProxyEnumerate(proxy) {
  var handler = %GetHandler(proxy)
  if (IS_UNDEFINED(handler.enumerate)) {
    return %Apply(DerivedEnumerateTrap, handler, [], 0, 0)
  } else {
    return ToStringArray(handler.enumerate(), "enumerate")
  }
}
<|endoftext|>


<commit_before>/**
 * 简单的抓取号码归属网站http://www.jihaoba.com/haoduan/139/jiaxing.htm的电话号码
 * 然后下载为本地excel(.xls)文件
 * 如果mocrosoft execl打不开的话或者总是错误提示请用wps打开
 * @authors singcl (24661881@qq.com)
 * @date    2018-07-17 18:16:03
 * @version v0.0.1
 */

var lis = document.getElementsByClassName("hd-city")[1].children;
var number = [];
var provence = [];
var city = [];
var quhao = [];
var yunshang = [];

for (var i = 0; i < lis.length; i++) {
    switch (lis[i].className) {
        case "hd-city01":
            number.push(lis[i].children[0].innerHTML);
            break;
        case "hd-city02":
            provence.push(lis[i].innerText);
            break;
        case "hd-city03":
            city.push(lis[i].innerText);
            break;
        case "hd-city04":
            quhao.push(lis[i].innerText);
            break;
        case "hd-city06":
            yunshang.push(lis[i].innerText);
            break;
        default:
            break;
    }

    //      console.log(lis[i])
}

var len = number.length;
var table = [];
for (var i = 0; i < len; i++) {
    table.push(`

        ${number[i]}
        ${provence[i]}
        ${city[i]}
        ${quhao[i]}
        ${yunshang[i]}

`);
}

var html = `

        <meta charset='utf-8' />

              号码段
              省份
              城市
              区号
              运营商

            ${table.join("\n")}

`;

var blobExcel = new Blob([html], {
    type: "application/vnd.ms-excel"
});

var oA = document.createElement("a");
oA.href = URL.createObjectURL(blobExcel);
oA.download = "haoma.xls";
oA.click();

// console.log(number,provence, city, quhao, yunshang)
<commit_msg>:art: table=>excel html样式在execl中同样生效！！<commit_after>/**
 * 简单的抓取号码归属网站http://www.jihaoba.com/haoduan/139/jiaxing.htm的电话号码
 * 然后下载为本地excel(.xls)文件
 * 如果mocrosoft execl打不开的话或者总是错误提示请用wps打开
 * @authors singcl (24661881@qq.com)
 * @date    2018-07-17 18:16:03
 * @version v0.0.1
 */

var lis = document.getElementsByClassName("hd-city")[1].children;
var number = [];
var provence = [];
var city = [];
var quhao = [];
var yunshang = [];

for (var i = 0; i < lis.length; i++) {
    switch (lis[i].className) {
        case "hd-city01":
            number.push(lis[i].children[0].innerHTML);
            break;
        case "hd-city02":
            provence.push(lis[i].innerText);
            break;
        case "hd-city03":
            city.push(lis[i].innerText);
            break;
        case "hd-city04":
            quhao.push(lis[i].innerText);
            break;
        case "hd-city06":
            yunshang.push(lis[i].innerText);
            break;
        default:
            break;
    }

    //      console.log(lis[i])
}

var len = number.length;
var table = [];
for (var i = 0; i < len; i++) {
    table.push(`

        ${number[i]}
        ${provence[i]}
        ${city[i]}
        ${quhao[i]}
        ${yunshang[i]}

`);
}

var html = `

        <meta charset='utf-8' />

              号码段
              省份
              城市
              区号
              运营商

            ${table.join("\n")}

`;

var blobExcel = new Blob([html], {
    type: "application/vnd.ms-excel"
});

var oA = document.createElement("a");
oA.href = URL.createObjectURL(blobExcel);
oA.download = "haoma.xls";
oA.click();

// console.log(number,provence, city, quhao, yunshang)
<|endoftext|>


<commit_before>/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Syntax highlighting addition/removal handlers (content scripts).
 *
 * First we need to decide whether we do or undo highlight.
 *
 * To do it, we have to add a CSS stylesheet and to enclose

 blocks
 * content to highlight with  tags so that it looks like
 *
 int a = 3 + b;
 (see highlightjs doc).
 * We perform a backup of original document by putting it in a hidden div.
 *
 * Undoing highlight consists in getting saved document back from the div.
 */

/*****************************************************************************/
var options = {};

/*
 * Run the main function at startup.
 */
var enlight = function () {
  /*
   * Get options attached as window.enlightContentScriptOptions by previous
   * content script.
   */
  options = enlightContentScriptOptions;

  /*
   * If there is no

 HTML block, there's nothing to work on: get
   * out of here.
   */
  if (!document.body ||
       document.body.getElementsByTagName("pre").item(0) === null)
    return;

  var initDocumentDiv = document.getElementById("enlightInitDocument");
  /*
   * If div is found, we already got syntax highlighting: let's undo it.
   * Else, launch highlighting.
   */
  initDocumentDiv === null ? dohl() : undohl(initDocumentDiv.firstChild);

  /*
   * If option is set, activate “gotoline” functionality.
   */
  if (options && options.lineNumbers)
    gotoline();
} ();

/*****************************************************************************/

function dohl() {
  var preList = document.getElementsByTagName("pre");
  /*
   * If options is empty we shouldn't be there. Page has probably been changed
   * since a former highlight: get out as well.
   * If options.language is "undo", we want to undo highlighting. If we
   * triggered dohl() in that case, we probably messed up somewhere in keeping
   * track of page status. Stop the mess here and return.
   */
  if (!options || options == {} || options.language == "undo")
    return;

  /*
   * Back up initial document
   */
  var clone = document.documentElement.cloneNode(true);
  var idoc  = document.createElement("div");
  idoc.style.display = "none";
  idoc.setAttribute("id", "enlightInitDocument");
  idoc.appendChild(clone);

  /*
   * If needed, add CSS rules for line numbering
   */
  addLineNumberStyle();

  /*
   * Deal with language
   */
  var language = "";

  if (options.language != "" && options.language != "auto") {
    language = " " + options.language;
  } else if (options.language == "auto" && options.fileExt) {
    /* Try to guess language based on file extension */
    let extension = window.location.toString().split('.').pop().toLowerCase();
    switch (extension) {
    case "sh":
      language = " bash";
      break;
    case "c":
    case "h":
      language = " c";
      break;
    case "cc":
      language = " cpp";
      break;
    case "diff":
    case "patch":
      language = " diff";
    case "js":
      language = " javascript";
      break;
    case "md":
      language = " markdown";
      break;
    case "pl":
      language = " perl";
      break;
    case "py":
      language = " python";
      break;
    case "rb":
      language = " ruby";
      break;
    case "rs":
      language = " rust";
      break;
    case "cs":
    case "css":
    case "go":
    case "xml":
    case "ini":
    case "json":
    case "java":
    case "php":
      language = " " + extension;
      break;
    case "txt":
      language = " nohighlight";
      break;
    default:
      break;
    }
  }
  /*
   * Else if (options.language == "auto"), we leave language to "" so
   * highlihgt.sh attempts auto-detection
   */

  /*
   * Enclose

 blocks content in  blocks
   */
  for (var pre of preList) {
    var firstChild = pre.firstChild;
    var code = document.createElement("code");
    code.setAttribute("class", "hljs" + language);
    code.style = "padding: 0;";
    code.appendChild(firstChild);
    pre.appendChild(code);
  }

  /*
   * Call highlighting function: hljs is defined in highlight.js library.
   */
  if (options && options.langList)
    hljs.configure({
      languages: options.langList
    });
  hljs.initHighlighting();

  /*
   * Add line numbers if needed.
   */
  if (options.lineNumbers)
    for (var pre of preList) {
      var code = pre.firstChild;
      addLineNumbers(code);
    }

  /*
   * There's a remaining white border because of body background color. Remove
   * it by copying background color of highlighted code area.
   */
  setTimeout(function () { // Wait for CSS to be computed
    let codeBG = getComputedStyle(preList[0].firstChild)["background-color"];
    if (codeBG &&
        codeBG!="white" &&
        codeBG!="#FFFFFF" &&
        codeBG!="#ffffff")
      document.body.style.backgroundColor = codeBG;
  }, 50);

  /*
   * If we launched language auto-detection, tell main script about detected
   * language
   */
  if (options.language == "" || options.language == "auto") {
    let languageClass = document.querySelectorAll("pre code")[0].className;
    let languageId = languageClass.slice("hljs ".length);
    let port = browser.runtime.connect({name: "detectedLanguage"});
    port.postMessage({language: languageId});
    port.disconnect();
  }

  /*
   * Save previous document in a hidden div to restore it on undohl()
   */
  document.body.appendChild(idoc);
}

/*****************************************************************************/

function undohl(idoc) {
  document.replaceChild(idoc, document.documentElement);
  /*
   * Another solution:
   * window.location.reload(false);
   */
}

/*****************************************************************************/

/*
 * Add line numbers to argument code block if option is set
 */
function addLineNumbers(aCode) {
  /*
   * Enclose each line of highlighted content into a "line" span.
   * Text has already been highlighted at this point (it's a mix of text
   * and of spans for coloring), so I can't see any easy way to do this
   * without assigning to innerHTML.
   */
  var lines = aCode.innerHTML
    .replace(/^.*?(\n|.$)/gm, '$&');
  aCode.innerHTML = lines;
}

/*****************************************************************************/

/*
 * Numbering is performed with CSS. We add it to head of document. From
 * https://github.com/isagalaev/highlight.js/compare/master...line-numbers
 */
function addLineNumberStyle() {
  if (!options.lineNumbers)
    return;

  var styleContent = " \
    pre { \
      counter-reset: lines; \
    } \
    pre .line { \
      counter-increment: lines; \
    } \
    pre .line::before { \
      -moz-user-select: none; \
      \
      content: counter(lines); text-align: right; \
      display: inline-block; min-width: 2.5em; \
      padding-right: 0.5em; margin-right: 0.5em; \
      font-weight: bold; \
      border-right: solid 1px; \
    }";
  var style = document.createElement("style");
  style.setAttribute("type", "text/css");
  var styleTextNode = document.createTextNode(styleContent);
  style.appendChild(styleTextNode);
  document.head.appendChild(style);
}

/*****************************************************************************/

/*
 * If user added an anchor to the URL, go to line number and select this line.
 * NOTE: there is no event triggered by URL edit that we could listen to, so
 * the anchor must be present when the script loads. If user adds it afterward,
 * they should manually reload the script (or the page if using autodetection).
 */
function gotoline() {
  /*
   * Get "#line27" or "#Line27" or "#L27" or "#l27" -like sequence from URL
   */
  let nb = (window.location + "").match(/#(?:[Ll](?:ine)?)?(\d+)/i)
  if (nb === null)
    return;

  /*
   * Fetch associated line. Note that we fetch the “absolute” nth line of
   * highlighted code in the file, which is not necessarily the nth line of its
   * block if there are several highlighted blocks of code.
   */
  let target = document.getElementsByClassName("line")[nb[1]-1]
  if (target === undefined)
    return;

  /*
   * Scroll to that line
   */
  target.scrollIntoView();

  /*
   * Select this line
   */
  let selection = window.getSelection();
  let range = document.createRange();
  range.setStartAfter(target);
  let next = document.getElementsByClassName("line")[nb[1]];
  next !== undefined ?
    range.setEndBefore(next) :
    range.setEndAfter(target.parentNode);
  selection.addRange(range);
}
<commit_msg>Fix .diff/.patch file-extension-based detection<commit_after>/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Syntax highlighting addition/removal handlers (content scripts).
 *
 * First we need to decide whether we do or undo highlight.
 *
 * To do it, we have to add a CSS stylesheet and to enclose

 blocks
 * content to highlight with  tags so that it looks like
 *
 int a = 3 + b;
 (see highlightjs doc).
 * We perform a backup of original document by putting it in a hidden div.
 *
 * Undoing highlight consists in getting saved document back from the div.
 */

/*****************************************************************************/
var options = {};

/*
 * Run the main function at startup.
 */
var enlight = function () {
  /*
   * Get options attached as window.enlightContentScriptOptions by previous
   * content script.
   */
  options = enlightContentScriptOptions;

  /*
   * If there is no

 HTML block, there's nothing to work on: get
   * out of here.
   */
  if (!document.body ||
       document.body.getElementsByTagName("pre").item(0) === null)
    return;

  var initDocumentDiv = document.getElementById("enlightInitDocument");
  /*
   * If div is found, we already got syntax highlighting: let's undo it.
   * Else, launch highlighting.
   */
  initDocumentDiv === null ? dohl() : undohl(initDocumentDiv.firstChild);

  /*
   * If option is set, activate “gotoline” functionality.
   */
  if (options && options.lineNumbers)
    gotoline();
} ();

/*****************************************************************************/

function dohl() {
  var preList = document.getElementsByTagName("pre");
  /*
   * If options is empty we shouldn't be there. Page has probably been changed
   * since a former highlight: get out as well.
   * If options.language is "undo", we want to undo highlighting. If we
   * triggered dohl() in that case, we probably messed up somewhere in keeping
   * track of page status. Stop the mess here and return.
   */
  if (!options || options == {} || options.language == "undo")
    return;

  /*
   * Back up initial document
   */
  var clone = document.documentElement.cloneNode(true);
  var idoc  = document.createElement("div");
  idoc.style.display = "none";
  idoc.setAttribute("id", "enlightInitDocument");
  idoc.appendChild(clone);

  /*
   * If needed, add CSS rules for line numbering
   */
  addLineNumberStyle();

  /*
   * Deal with language
   */
  var language = "";

  if (options.language != "" && options.language != "auto") {
    language = " " + options.language;
  } else if (options.language == "auto" && options.fileExt) {
    /* Try to guess language based on file extension */
    let extension = window.location.toString().split('.').pop().toLowerCase();
    switch (extension) {
    case "sh":
      language = " bash";
      break;
    case "c":
    case "h":
      language = " c";
      break;
    case "cc":
      language = " cpp";
      break;
    case "diff":
    case "patch":
      language = " diff";
      break;
    case "js":
      language = " javascript";
      break;
    case "md":
      language = " markdown";
      break;
    case "pl":
      language = " perl";
      break;
    case "py":
      language = " python";
      break;
    case "rb":
      language = " ruby";
      break;
    case "rs":
      language = " rust";
      break;
    case "cs":
    case "css":
    case "go":
    case "xml":
    case "ini":
    case "json":
    case "java":
    case "php":
      language = " " + extension;
      break;
    case "txt":
      language = " nohighlight";
      break;
    default:
      break;
    }
  }
  /*
   * Else if (options.language == "auto"), we leave language to "" so
   * highlihgt.sh attempts auto-detection
   */

  /*
   * Enclose

 blocks content in  blocks
   */
  for (var pre of preList) {
    var firstChild = pre.firstChild;
    var code = document.createElement("code");
    code.setAttribute("class", "hljs" + language);
    code.style = "padding: 0;";
    code.appendChild(firstChild);
    pre.appendChild(code);
  }

  /*
   * Call highlighting function: hljs is defined in highlight.js library.
   */
  if (options && options.langList)
    hljs.configure({
      languages: options.langList
    });
  hljs.initHighlighting();

  /*
   * Add line numbers if needed.
   */
  if (options.lineNumbers)
    for (var pre of preList) {
      var code = pre.firstChild;
      addLineNumbers(code);
    }

  /*
   * There's a remaining white border because of body background color. Remove
   * it by copying background color of highlighted code area.
   */
  setTimeout(function () { // Wait for CSS to be computed
    let codeBG = getComputedStyle(preList[0].firstChild)["background-color"];
    if (codeBG &&
        codeBG!="white" &&
        codeBG!="#FFFFFF" &&
        codeBG!="#ffffff")
      document.body.style.backgroundColor = codeBG;
  }, 50);

  /*
   * If we launched language auto-detection, tell main script about detected
   * language
   */
  if (options.language == "" || options.language == "auto") {
    let languageClass = document.querySelectorAll("pre code")[0].className;
    let languageId = languageClass.slice("hljs ".length);
    let port = browser.runtime.connect({name: "detectedLanguage"});
    port.postMessage({language: languageId});
    port.disconnect();
  }

  /*
   * Save previous document in a hidden div to restore it on undohl()
   */
  document.body.appendChild(idoc);
}

/*****************************************************************************/

function undohl(idoc) {
  document.replaceChild(idoc, document.documentElement);
  /*
   * Another solution:
   * window.location.reload(false);
   */
}

/*****************************************************************************/

/*
 * Add line numbers to argument code block if option is set
 */
function addLineNumbers(aCode) {
  /*
   * Enclose each line of highlighted content into a "line" span.
   * Text has already been highlighted at this point (it's a mix of text
   * and of spans for coloring), so I can't see any easy way to do this
   * without assigning to innerHTML.
   */
  var lines = aCode.innerHTML
    .replace(/^.*?(\n|.$)/gm, '$&');
  aCode.innerHTML = lines;
}

/*****************************************************************************/

/*
 * Numbering is performed with CSS. We add it to head of document. From
 * https://github.com/isagalaev/highlight.js/compare/master...line-numbers
 */
function addLineNumberStyle() {
  if (!options.lineNumbers)
    return;

  var styleContent = " \
    pre { \
      counter-reset: lines; \
    } \
    pre .line { \
      counter-increment: lines; \
    } \
    pre .line::before { \
      -moz-user-select: none; \
      \
      content: counter(lines); text-align: right; \
      display: inline-block; min-width: 2.5em; \
      padding-right: 0.5em; margin-right: 0.5em; \
      font-weight: bold; \
      border-right: solid 1px; \
    }";
  var style = document.createElement("style");
  style.setAttribute("type", "text/css");
  var styleTextNode = document.createTextNode(styleContent);
  style.appendChild(styleTextNode);
  document.head.appendChild(style);
}

/*****************************************************************************/

/*
 * If user added an anchor to the URL, go to line number and select this line.
 * NOTE: there is no event triggered by URL edit that we could listen to, so
 * the anchor must be present when the script loads. If user adds it afterward,
 * they should manually reload the script (or the page if using autodetection).
 */
function gotoline() {
  /*
   * Get "#line27" or "#Line27" or "#L27" or "#l27" -like sequence from URL
   */
  let nb = (window.location + "").match(/#(?:[Ll](?:ine)?)?(\d+)/i)
  if (nb === null)
    return;

  /*
   * Fetch associated line. Note that we fetch the “absolute” nth line of
   * highlighted code in the file, which is not necessarily the nth line of its
   * block if there are several highlighted blocks of code.
   */
  let target = document.getElementsByClassName("line")[nb[1]-1]
  if (target === undefined)
    return;

  /*
   * Scroll to that line
   */
  target.scrollIntoView();

  /*
   * Select this line
   */
  let selection = window.getSelection();
  let range = document.createRange();
  range.setStartAfter(target);
  let next = document.getElementsByClassName("line")[nb[1]];
  next !== undefined ?
    range.setEndBefore(next) :
    range.setEndAfter(target.parentNode);
  selection.addRange(range);
}
<|endoftext|>


<commit_before>// Add the addLoadEvent function first so that is always ready to fire...
// note the first onload event should be the debug_list code!!

function _time_diff(x) {
  var d = new Date();
  return ((d.getTime()-x.getTime())/1000).toFixed(3);
}
function addLoadEvent(func) {
  var oldonload = window.onload;
  if( typeof window.onload != 'function' ) {
    window.onload = function() {
      var t = new Date();
      func();
      if( $('debug_list') ) {
        var x = func.toString().split(/\(/);
	if(!x) x = func;
	__info(x[0]+' ('+ _time_diff(t)+'s)');
      }
    }
  } else {
    window.onload = function() {
      oldonload();
      var t = new Date();
      func();
      if( $('debug_list') ) {
        var x = func.toString().split(/\(/);
	if(!x) x = func;
	__info(x[0]+' ('+_time_diff(t)+'s)');
      }
    };
  }
}

<commit_msg>added code to randomly name the window<commit_after>// Add the addLoadEvent function first so that is always ready to fire...
// note the first onload event should be the debug_list code!!

function _time_diff(x) {
  var d = new Date();
  return ((d.getTime()-x.getTime())/1000).toFixed(3);
}
function addLoadEvent(func) {
  var oldonload = window.onload;
  if( typeof window.onload != 'function' ) {
    window.onload = function() {
      var t = new Date();
      func();
      if( $('debug_list') ) {
        var x = func.toString().split(/\(/);
	if(!x) x = func;
	__info(x[0]+' ('+ _time_diff(t)+'s)');
      }
    }
  } else {
    window.onload = function() {
      oldonload();
      var t = new Date();
      func();
      if( $('debug_list') ) {
        var x = func.toString().split(/\(/);
	if(!x) x = func;
	__info(x[0]+' ('+_time_diff(t)+'s)');
      }
    };
  }
}

function _name_window() {
  if(!window.name) {
    var d = new Date();
    window.name = 'ensembl_'+d.getTime()+'_'+Math.floor(Math.random()*10000);
  }
}

addLoadEvent(_name_window);
<|endoftext|>


<commit_before>var con = (function (module, opts) {

	if (window.performance.getEntries) {
		opts = opts || {};
		var output = document.createElement('div'),
			css = '#perf{background:' + (opts.background || '#FFF') + ';position:fixed;bottom:0;color:' + (opts.color || '#639') + ';left:0;padding:10px;overflow:auto;height:300px;z-index:1000;width:100%;line-height:20px;font-weight:bold}' +
				'#perf .dr{width:100%; padding:5px;text-align:right}' +
				'#perf div{padding:5px;border-top:solid 1px}' +
				'#perf div:nth-child(even){background-color:' + (opts.rowColor || '#eee') + '}' +
				'#perf span{display:inline-block;width:24.9%}' +
				'#perf .n {width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;}',
			head = document.head || document.getElementsByTagName('head')[0],
			style = document.createElement('style');

		style.type = 'text/css';

		if (style.styleSheet) {
			style.styleSheet.cssText = css;
		} else {
			style.appendChild(document.createTextNode(css));
		}

		head.appendChild(style);
		output.setAttribute('id', 'perf');
		document.body.appendChild(output);
	}

	module.perf = function () {
		if (window.performance.getEntries) {
			var e = performance.getEntries(),
				elem = document.querySelector('#perf'),
				output = '', perfData = performance.timing,
				domReady = perfData.loadEventEnd - perfData.navigationStart,
				connectTime = perfData.responseEnd - perfData.requestStart;

			// Sort the results on start time;
			e = e.sort(function (a, b) {
				return parseFloat(a.responseStart) - parseFloat(b.responseStart);
			});

			console.info(connectTime + 'ms');
			output += 'DOM Ready: ' + domReady + 'ms';

			for (var i = 0; i < e.length; i++) {
				output += '
';
				output += '' + e[i].name + '';
				output += '' + e[i].responseStart.toFixed(2) /* Download Starts */ + 'ms';
				output += '' + e[i].responseEnd.toFixed(2) /* Download Ends */ + 'ms';
				output += '' + (e[i].responseEnd - e[i].responseStart).toFixed(2) /* Total Download Time */ + 'ms';
				output += '' + e[i].duration.toFixed(2) /* End to End */ + 'ms';
				output += '
';
			}

			elem.innerHTML = output;
		}
	};

	return module;
} (con || {}));

con.perf();<commit_msg>Adding new features<commit_after>/*
 * Options
 */
/*var opts = {
  background: '#fff',
  color: '#639',
	rowColor: '#eee'
};
*/
var con = (function (module, opts) {

	if (window.performance.getEntries) {
		opts = opts || {};
		var data = performance.getEntries(),
			output = document.createElement('div'),
			css = '#perf{background:' + (opts.background || '#FFF') + ';position:fixed;bottom:0;color:' + (opts.color || '#639') + ';left:0;padding:10px;overflow:auto;height:300px;z-index:1000;width:100%;line-height:20px;font-weight:bold}' +
				'#perf .dr{width:100%; padding:5px;text-align:right}' +
				'#perf div{padding:5px;border-top:solid 1px}' +
				'#perf div:nth-child(even){background-color:' + (opts.rowColor || '#eee') + '}' +
				'#perf span{display:inline-block;width:24.9%}' +
				'#perf .n {width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;}',
			head = document.head || document.getElementsByTagName('head')[0],
			style = document.createElement('style');

		style.type = 'text/css';

		if (style.styleSheet) {
			style.styleSheet.cssText = css;
		} else {
			style.appendChild(document.createTextNode(css));
		}

		head.appendChild(style);
		output.setAttribute('id', 'perf');
		document.body.appendChild(output);
	}

	module.perf = function () {
		if (window.performance.getEntries) {
				var elem = document.querySelector('#perf'),
				output = '', perfData = performance.timing,
				domReady = perfData.loadEventEnd - perfData.navigationStart,
				connectTime = perfData.responseEnd - perfData.requestStart;

			// Sort the results on start time;
			data = data.sort(function (a, b) {
				return parseFloat(a.responseStart) - parseFloat(b.responseStart);
			});

			console.info(connectTime + 'ms');
			output += 'DOM Ready: ' + domReady + 'ms';

			for (var i = 0; i < data.length; i++) {
				output += '
';
				output += '' + data[i].name + '';
				output += '' + data[i].responseStart.toFixed(2) /* Download Starts */ + 'ms';
				output += '' + data[i].responseEnd.toFixed(2) /* Download Ends */ + 'ms';
				output += '' + (data[i].responseEnd - data[i].responseStart).toFixed(2) /* Total Download Time */ + 'ms';
				output += '' + data[i].duration.toFixed(2) /* End to End */ + 'ms';
				output += '
';
			}

			elem.innerHTML = output;
		};

		module.getDetail = function(idx){
			// TODO - Add detail: DNS lookup, open the connection, SSL, etc
		};
	};

	return module;
} (con || {}));

con.perf();<|endoftext|>


<commit_before>'use strict';

angular.module('core').controller('HomeController', ['$scope', '$interval', 'Authentication', 'ActiveEvent',
  function ($scope, $interval, Authentication, ActiveEvent) {
    // This provides Authentication context.
    $scope.authentication = Authentication;

    $scope.init = function() {
      ActiveEvent.get().then(function(activeEvent) {
        $scope.activeEvent = activeEvent;
        $interval($scope.calcEventTime, 1000);
      });
    };

    $scope.calcEventTime = function() {
      var now = new Date();
      var timeLeft, timeTill;
      var days, hours, minutes, seconds;
      var startDate = new Date($scope.activeEvent.start);
      var endDate = new Date($scope.activeEvent.end);

      if (startDate < now) {
        $scope.activeEvent.inProgress = true;
        timeLeft = parseInt((endDate - now) / 1000); // Time left in seconds
        hours = parseInt(timeLeft / (60*60));
        minutes = parseInt((timeLeft - hours * 60 * 60) / 60);
        seconds = timeLeft - hours * 60 * 60 - minutes * 60;
        $scope.activeEvent.timer = hours + ':' + minutes + ':' + seconds;
      } else {
        $scope.activeEvent.inProgress = false;
        timeTill = parseInt((startDate - now) / 1000); // Time till in seconds
        days = parseInt(timeTill / (24 * 60 * 60));
        hours = parseInt((timeTill - days * 24 * 60 * 60) / 60 / 60);
        minutes = parseInt((timeTill - days * 24 * 60 * 60 - hours * 60 * 60) / 60);
        $scope.activeEvent.timer = days + ' days, ' + hours + ' hours, ' + minutes + ' minutes';
      }
    };
  }
]);
<commit_msg>Show interval timer immediately<commit_after>'use strict';

angular.module('core').controller('HomeController', ['$scope', '$interval', 'Authentication', 'ActiveEvent',
  function ($scope, $interval, Authentication, ActiveEvent) {
    // This provides Authentication context.
    $scope.authentication = Authentication;

    $scope.init = function() {
      ActiveEvent.get().then(function(activeEvent) {
        $scope.activeEvent = activeEvent;
        $scope.calcEventTime();
        $interval($scope.calcEventTime, 1000);
      });
    };

    $scope.calcEventTime = function() {
      var now = new Date();
      var timeLeft, timeTill;
      var days, hours, minutes, seconds;
      var startDate = new Date($scope.activeEvent.start);
      var endDate = new Date($scope.activeEvent.end);

      if (startDate < now) {
        $scope.activeEvent.inProgress = true;
        timeLeft = parseInt((endDate - now) / 1000); // Time left in seconds
        hours = parseInt(timeLeft / (60*60));
        minutes = parseInt((timeLeft - hours * 60 * 60) / 60);
        seconds = timeLeft - hours * 60 * 60 - minutes * 60;
        $scope.activeEvent.timer = hours + ':' + minutes + ':' + seconds;
      } else {
        $scope.activeEvent.inProgress = false;
        timeTill = parseInt((startDate - now) / 1000); // Time till in seconds
        days = parseInt(timeTill / (24 * 60 * 60));
        hours = parseInt((timeTill - days * 24 * 60 * 60) / 60 / 60);
        minutes = parseInt((timeTill - days * 24 * 60 * 60 - hours * 60 * 60) / 60);
        $scope.activeEvent.timer = days + ' days, ' + hours + ' hours, ' + minutes + ' minutes';
      }
    };
  }
]);
<|endoftext|>


<commit_before>'use strict';

angular.module('core').controller('HomeController', ['$scope','Authentication','$facebook',
  function ($scope, Authentication,$facebook) {
    // This provides Authentication context.
    $scope.authentication = Authentication;
      $scope.loadFriends = function() {
          $facebook.api("/me/friends").then(
              function(response) {
                  $scope.myFriends = "Welcome " +response.data;
              },
              function(err) {
                  $scope.myFriends = "Please log in";
              });
      };
  }
]);
<commit_msg>fb post<commit_after>'use strict';

angular.module('core').controller('HomeController', ['$scope','Authentication','$facebook',
  function ($scope, Authentication,$facebook) {
    // This provides Authentication context.
    $scope.authentication = Authentication;
      $scope.loadFriends = function() {
          $facebook.api("/me/friends").then(
              function(response) {
                  $scope.myFriends = "Welcome " +response.data[0];
              },
              function(err) {
                  $scope.myFriends = "Please log in";
              });
      };
  }
]);
<|endoftext|>


<commit_before>var promisify = require("promisify-node");
var path = require("path");
var fs = require("fs");

var prepareForBuild = require("./prepareForBuild");

var exec = promisify(function(command, opts, callback) {
  return require("child_process").exec(command, opts, callback);
});

var local = path.join.bind(path, __dirname);

if (fs.existsSync(local("../.didntcomefromthenpmregistry"))) {
  return prepareAndBuild();
}
if (process.env.BUILD_DEBUG) {
  console.info("[nodegit] Doing a debug build, no fetching allowed.");
  return prepareAndBuild();
}
if (process.env.BUILD_ONLY) {
  console.info("[nodegit] BUILD_ONLY is set to true, no fetching allowed.");
  return prepareAndBuild();
}

return installPrebuilt();

function installPrebuilt() {
  console.info("[nodegit] Fetching binary from S3.");
  return exec("node-pre-gyp install --fallback-to-build=false")
    .then(
      function() {
        console.info("[nodegit] Completed installation successfully.");
      },
      function(err) {
        console.info("[nodegit] Failed to install prebuilt binary:");
        console.error(err);
        console.info("[nodegit] Building manually. (You'll be here a while.)");
        return prepareAndBuild();
      }
    );
}

function prepareAndBuild() {
  console.info("[nodegit] Regenerating and configuring code");
  return prepareForBuild()
    .then(function() {
      return build();
    });
}

function build() {
  console.info("[nodegit] Everything is ready to go, attempting compilation");

  var opts = {
    cwd: ".",
    maxBuffer: Number.MAX_VALUE,
    env: process.env
  };

  var debug = (process.env.BUILD_DEBUG ? " --debug" : "");
  var builder = "node-gyp";

  var home = process.platform == "win32" ?
              process.env.USERPROFILE : process.env.HOME;

  opts.env.HOME = path.join(home, ".nodegit-gyp");

  builder = path.resolve(".", "node_modules", ".bin", builder);
  builder = builder.replace(/\s/g, "\\$&");
  var cmd = [builder, "rebuild", debug].join(" ").trim();

  return exec(cmd, opts)
    .then(function() {
        console.info("[nodegit] Compilation complete.");
        console.info("[nodegit] Completed installation successfully.");
        process.exitCode = 0;
      },
      function(err, stderr) {
        console.error(err);
        console.error(stderr);
        process.exitCode = 13;
      }
    );
}
<commit_msg>Get the right path for tools.<commit_after>var promisify = require("promisify-node");
var path = require("path");
var fs = require("fs");

var prepareForBuild = require("./prepareForBuild");

var exec = promisify(function(command, opts, callback) {
  return require("child_process").exec(command, opts, callback);
});

var local = path.join.bind(path, __dirname);

if (fs.existsSync(local("../.didntcomefromthenpmregistry"))) {
  return prepareAndBuild();
}
if (process.env.BUILD_DEBUG) {
  console.info("[nodegit] Doing a debug build, no fetching allowed.");
  return prepareAndBuild();
}
if (process.env.BUILD_ONLY) {
  console.info("[nodegit] BUILD_ONLY is set to true, no fetching allowed.");
  return prepareAndBuild();
}

return installPrebuilt();

function installPrebuilt() {
  console.info("[nodegit] Fetching binary from S3.");
  var npg = pathForTool("node-pre-gyp");
  return exec(npg + " install --fallback-to-build=false")
    .then(
      function() {
        console.info("[nodegit] Completed installation successfully.");
      },
      function(err) {
        console.info("[nodegit] Failed to install prebuilt binary:");
        console.error(err);
        console.info("[nodegit] Building manually. (You'll be here a while.)");
        return prepareAndBuild();
      }
    );
}

function pathForTool(name) {
  var toolPath = path.resolve(".", "node_modules", ".bin", name);
  toolPath = toolPath.replace(/\s/g, "\\$&");
  return toolPath;
}

function prepareAndBuild() {
  console.info("[nodegit] Regenerating and configuring code");
  return prepareForBuild()
    .then(function() {
      return build();
    });
}

function build() {
  console.info("[nodegit] Everything is ready to go, attempting compilation");

  var opts = {
    cwd: ".",
    maxBuffer: Number.MAX_VALUE,
    env: process.env
  };

  var debug = (process.env.BUILD_DEBUG ? " --debug" : "");

  var home = process.platform == "win32" ?
              process.env.USERPROFILE : process.env.HOME;

  opts.env.HOME = path.join(home, ".nodegit-gyp");

  var builder = pathForTool("node-gyp");
  var cmd = [builder, "rebuild", debug].join(" ").trim();

  return exec(cmd, opts)
    .then(function() {
        console.info("[nodegit] Compilation complete.");
        console.info("[nodegit] Completed installation successfully.");
        process.exitCode = 0;
      },
      function(err, stderr) {
        console.error(err);
        console.error(stderr);
        process.exitCode = 13;
      }
    );
}
<|endoftext|>


<commit_before>import React from 'react';
import Board from '@/modules/core/client/components/Board.js';
import { useTranslation } from 'react-i18next';

export default function Volunteering() {
  const { t } = useTranslation('pages');

  return (
    <>
      <Board
        className="volunteer-header board-happyhippies"
        names="happyhippies"
      >

{t('Volunteering')}

      </Board>

              {t(
                'Help us build Trustroots! Nobody can do everything, but everyone can do something…',
              )}

              {t(
                'Trustroots needs developers, designers, people handling support queue, copywriting and much more.',
              )}

              {t(
                'Please head over to our Team Guide to learn how to get started.',
              )}

                  {t('Team Guide')}

                  {t('Meet the team')}

    </>
  );
}

Volunteering.propTypes = {};
<commit_msg>Run Prettier formatter on updated file<commit_after>import React from 'react';
import Board from '@/modules/core/client/components/Board.js';
import { useTranslation } from 'react-i18next';

export default function Volunteering() {
  const { t } = useTranslation('pages');

  return (
    <>
      <Board
        className="volunteer-header board-happyhippies"
        names="happyhippies"
      >

{t('Volunteering')}

      </Board>

              {t(
                'Help us build Trustroots! Nobody can do everything, but everyone can do something…',
              )}

              {t(
                'Trustroots needs developers, designers, people handling support queue, copywriting and much more.',
              )}

              {t(
                'Please head over to our Team Guide to learn how to get started.',
              )}

                    {t('Team Guide')}

                  {t('Meet the team')}

    </>
  );
}

Volunteering.propTypes = {};
<|endoftext|>


<commit_before>'use strict'

var Promise = require('q');
var _ = require('./lodash')

module.exports = function(service) {
  var reductiofy = require('./reductiofy')(service)
  var filters = require('./filters')(service)
  var postAggregation = require('./postAggregation')(service)

  return function query(query) {

    // Default query
    if (typeof(query) === 'undefined') {
      query = {}
    }

    // Default select
    if (typeof(query.select) === 'undefined') {
      query.select = {
        $count: true
      }
    }

    // Support groupAll
    query.groupBy = query.groupBy || true

    // Find Existing Column
    var column = service.column.find(query.groupBy)

    var group

    return Promise.try(function() {
        // Create Column if not found
        if (!column) {
          return service.column({
              key: query.groupBy,
              type: !_.isUndefined(query.type) ? query.type : null,
              array: !!query.array
            })
            .then(function() {
              return service.column.find(query.groupBy)
            })
        }
        // If the column exists, let's at least make sure it's marked
        // as permanent. There is a slight chance it exists because
        // of a filter, and the user has now decided to query on it
        return column
      })
      .then(function(c) {
        column = c
          // Create the grouping on the columns dimension
          // Using Promise Resolve allows support for crossfilter async
          // TODO check if query already exists, and use the same base query // if possible
        return Promise.resolve(column.dimension.group())
      })
      .then(function(g) {
        // Save the group while we create the reducer
        group = g
        return filters.scanForDynamicFilters(query)
      })
      .then(function(requiredColumns) {
        // We need to scan the group for any filters that would require
        // the group to be rebuilt when data is added or removed in any way.
        if (requiredColumns.length) {
          return Promise.all(_.map(requiredColumns, function(columnKey) {
              return service.column({
                key: columnKey,
                dynamicReference: group
              })
            }))
            .then(function() {
              return true
            })
        }
        return false
      })
      .then(function(needsListener) {
        // Here, we create a listener to recreate and apply the reducer
        // (with updated reference data) to
        // the group anytime data changes.

        var queryRes = {
          // The Universe for continuous promise chaining
          universe: service,
          // The bare metalqueryRes.data
          crossfilter: service.cf,
          dimension: column.dimension,
          group: group,
          // Reductio reducer instance
          reducer: null,
          removeListeners: [],
          // original query passed in to query method
          original: query,
        };

        addQueryMethods(queryRes)
        column.queries.push(queryRes);

        var stopListeningForData
        if (needsListener) {
          stopListeningForData = service.onDataChange(function applyReducerOnDataChange(isPost) {
            return applyReducer(queryRes, isPost)
          })
          column.removeListeners.push(stopListeningForData)
        }

        return applyReducer(queryRes)
          .then(function() {
            return queryRes
          })

        function applyReducer(queryRes, isPost) {
          // Create the reducer using reductio and the Universe
          // Query Syntax
          return reductiofy(query)
            .then(function(reducer) {
              queryRes.reducer = reducer
                // Apply the reducer to the group
              queryRes.reducer(queryRes.group)
              return Promise.resolve(queryRes.group.all())
            })
            .then(function(all) {
              queryRes.data = all
            })
        }

        function addQueryMethods(q) {
          _.assign(q, postAggregation.getMethods(q), {
            clear: clearQuery,
          })

          function clearQuery() {
            _.forEach(q.removeListners, function(l) {
              l()
            })
            return Promise.try(function() {
                return q.group.dispose()
              })
              .then(function() {
                column.queries.splice(column.queries.indexOf(q), 1)
                if (!column.queries.length) {
                  return service.clear(column.key)
                }
              })
              .then(function() {
                return service
              })
          }
        }

      })
  }
}
<commit_msg>Flattened Query Promise Complexity<commit_after>'use strict'

var Promise = require('q');
var _ = require('./lodash')

module.exports = function(service) {
  var reductiofy = require('./reductiofy')(service)
  var filters = require('./filters')(service)
  var postAggregation = require('./postAggregation')(service)

  return function doQuery(queryObj) {

    var query
    var queryHash = JSON.stringify(queryObj)

    // Attempt to reuse an exact copy of this query that is present elsewhere
    for (var i = 0; i < service.columns.length; i++) {
      for (var j = 0; j < service.columns[i].queries.length; j++) {
        if (service.columns[i].queries[j].hash === queryHash) {
          return Promise.try(function() {
            return service.columns[i].queries[j]
          })
        }
      }
    }

    var query = {
      // The Universe for continuous promise chaining
      universe: service,
      // Parent column
      column: null,
      // Crossfilter instances
      crossfilter: service.cf,
      dimension: null,
      group: null,
      // Reductio reducer instance
      reducer: null,
      // Listeners
      removeListeners: [],
      // Post aggregations
      postAggregations: [],
      // Original query passed in to query method
      original: queryObj,
      hash: queryHash,
    }

    // Default queryObj
    if (_.isUndefined(query.original)) {
      query.original = {}
    }
    // Default select
    if (_.isUndefined(query.original.select)) {
      query.original.select = {
        $count: true
      }
    }
    // Default to groupAll
    query.original.groupBy = query.original.groupBy || true

    // Attach the query api to the query object
    addQueryMethods(query)

    return createColumn(query)
      .then(makeCrossfilterGroup)
      .then(buildRequiredColumns)
      .then(applyQuery)

    function createColumn(query) {
      // Ensure column is created
      return service.column({
          key: query.original.groupBy,
          type: !_.isUndefined(query.type) ? query.type : null,
          array: !!query.array
        })
        .then(function() {
          // Attach the column to the query
          var column = service.column.find(query.original.groupBy)
          query.column = column
          column.queries.push(query)
          return query
        })
    }

    function makeCrossfilterGroup(query) {
      // Create the grouping on the columns dimension
      // Using Promise Resolve allows support for crossfilter async
      // TODO check if query already exists, and use the same base query // if possible
      return Promise.resolve(query.column.dimension.group())
        .then(function(g) {
          query.group = g
          return query
        })
    }

    function buildRequiredColumns(query) {
      var requiredColumns = filters.scanForDynamicFilters(query.original)
        // We need to scan the group for any filters that would require
        // the group to be rebuilt when data is added or removed in any way.
      if (requiredColumns.length) {
        return Promise.all(_.map(requiredColumns, function(columnKey) {
            return service.column({
              key: columnKey,
              dynamicReference: query.group
            })
          }))
          .then(function() {
            // Here, we create a listener to recreate and apply the reducer
            // (with updated reference data) to
            // the group anytime data changes
            var stopListeningForData = service.onDataChange(function applyReducerOnDataChange() {
              return applyQuery(query)
            })
            query.column.removeListeners.push(stopListeningForData)
            return query
          })
      }
      return query
    }

    function applyQuery(query) {
      // Create the reducer using reductio and the Universe
      // Query Syntax
      return buildReducer(query)
        .then(applyReducer)
        .then(attachData)
    }

    function buildReducer(query) {
      return reductiofy(query.original)
        .then(function(reducer) {
          query.reducer = reducer
          return query
        })
    }

    function applyReducer(query) {
      return Promise.resolve(query.reducer(query.group))
        .then(function() {
          return query
        })
    }

    function attachData(query) {
      return Promise.resolve(query.group.all())
        .then(function(data) {
          query.data = data
          return query
        })
    }

    function applyPostAggregations(query) {
      return query
    }

    function addQueryMethods(q) {
      _.assign(q, postAggregation.getMethods(q), {
        clear: clearQuery,
      })

      function clearQuery() {
        _.forEach(q.removeListners, function(l) {
          l()
        })
        return Promise.try(function() {
            return q.group.dispose()
          })
          .then(function() {
            q.column.queries.splice(q.column.queries.indexOf(q), 1)
            if (!q.column.queries.length) {
              return service.clear(q.column.key)
            }
          })
          .then(function() {
            return service
          })
      }

    }
  }
}
<|endoftext|>


<commit_before>import co from 'co';
import { extend, merge } from 'extend-merge';
import { Model, Collector } from 'chaos-orm';

/**
 * The Query wrapper.
 */
class Query {

  /**
   * Gets/sets classes dependencies.
   *
   * @param  Object classes The classes dependencies to set or none to get it.
   * @return mixed          The classes dependencies.
   */
  static classes(classes) {
    if (arguments.length) {
      this._classes = extend({}, this._classes, classes);
    }
    return this._classes;
  }

  /**
   * Creates a new record object with default values.
   *
   * @param array config Possible options are:
   *                      - `'model'`  _Function_ : A model class.
   *                      - `'schema'` _Object_   : Alternatively a schema instance can be provided instead of the model.
   *                      - `'query'`  _Object_   : The query.
   */
  constructor(config) {
    var defaults = {
      model: undefined,
      schema: undefined,
      query: {}
    };
    config = extend({}, defaults, config);

    if (config.model) {
      this._model = config.model;
      this._schema = this._model.definition();
    } else {
      this._schema = config.schema;
    }

    /**
     * The connection to the datasource.
     *
     * @var Function
     */
    this._connection = config.connection;

    /**
     * Count the number of identical aliases in a query for building unique aliases.
     *
     * @var Object
     */
    this._aliasCounter = {};

    /**
     * Map beetween relation pathsand corresponding aliases.
     *
     * @var Object
     */
    this._aliases = {};

    /**
     * Map beetween generated aliases and corresponding schema.
     *
     * @var Object
     */
    this._schemas = {};

    /**
     * The relations to include.
     *
     * @var Array
     */
    this._embed = [];

    /**
     * Some conditions over some relations.
     *
     * @var Array
     */
    this._has = [];

    /**
     * Pagination.
     *
     * @var Array
     */
    this._page = [];

    var schema = this.schema();

    /**
     * The select statement instance.
     *
     * @var Function
     */
    this._statement = schema.connection().dialect().statement('select');

    var source = schema.source();
    var from = {};
    from[source] = this.alias('', schema);
    this.statement().from(from);

    for (var key in config.query) {
      this[key](config.query[key]);
    }
  }

  /**
   * Gets the schema.
   *
   * @return Function Returns the schema.
   */
  schema() {
    if (!this._schema) {
      throw new Error("Error, missing schema for this query.");
    }
    return this._schema;
  }

  /**
   * Gets the model.
   *
   * @return Function Returns the model.
   */
  model() {
    return this._model;
  }

  /**
   * Gets the query statement.
   *
   * @return Function Returns a connection instance.
   */
  statement() {
    return this._statement;
  }

  /**
   * Executes the query and returns the result.
   *
   * @param  Object  Options The fetching options.
   * @return Promise         A Promise.
   */
  get(options) {
    return co(function*(){
      var defaults = {
        collector: undefined,
        return: 'entity'
      };
      options = extend({}, defaults, options);

      var classname = this.constructor.classes().collector;
      var collector = options.collector = options.collector ? options.collector : new classname();

      this._applyHas();
      this._applyLimit();

      var noFields = !this.statement().data('fields').length;
      if (noFields) {
        var star = {};
        star[this.alias()] = ['*'];
        this.statement().fields([star]);
      }

      var collection = [];
      var ret = options['return'];

      var schema = this.schema();
      var cursor = yield schema.connection().query(this.statement().toString());

      switch (ret) {
        case 'entity':
          var source = schema.source();
          var key = schema.key();

          var model = this.model();
          if (!model) {
            throw new Error("Missing model for this query, set `'return'` to `'object'` to get row data.");
          }

          collection = model.create([], {
            collector: collector,
            type: 'set',
            exists: true
          });

          for (var record of cursor) {
            var uuid = source + ':' + record[key];
            if (record[key] && collector.has(uuid)) {
              collection.push(collector.get(uuid));
            } else {
              collection.push(model.create(record, {
                collector: collector,
                exists: noFields ? true : null
              }));
            }
          }
          break;
        case 'array':
        case 'object':
          for (var record of cursor) {
            collection.push(extend({}, record));
          }
          break;
        default:
          throw new Error("Invalid `'" + options['return'] + "'` mode as `'return'` value");
          break;
      }
      return schema.embed(collection, this._embed, { fetchOptions: options });
    }.bind(this));
  }

  /**
   * Alias for `get()`
   *
   * @return object An iterator instance.
   */
  all(options) {
    return this.get(options);
  }

  /**
   * Executes the query and returns the first result only.
   *
   * @return object An entity instance.
   */
  first(options) {
    return co(function*() {
      var result = yield this.get(options);
      return Array.isArray(result) ? result[0] : result.get(0);
    }.bind(this));
  }

  /**
   * Executes the query and returns the count number.
   *
   * @return integer The number of rows in result.
   */
  count() {
    return co(function*() {
      var schema = this.schema();
      this.statement().fields([{':plain': 'COUNT(*)'}]);
      var cursor = yield schema.connection().query(this.statement().toString());
      var result = cursor.next();
      var key = Object.keys(result)[0]
      return Number.parseInt(result[key]);
    }.bind(this));
  }

  /**
   * Adds some fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  fields(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);

    var schema = this.schema();

    for (var value of fields) {
      if (typeof value === 'string' && schema.has(value)) {
        var aliased = {};
        aliased[this.alias()] = [value]
        this.statement().fields(aliased);
      } else {
        this.statement().fields(value);
      }
    }
    return this;
  }

  /**
   * Adds some where conditions to the query
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  where(conditions, alias) {
    var conditions = this.statement().dialect().prefix(conditions, alias ? alias : this.alias(), false);
    this.statement().where(conditions);
    return this;
  }

  /**
   * Alias for `where()`.
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  conditions(conditions) {
    return this.where(conditions);
  }

  /**
   * Adds some group by fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  group(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);
    fields = this.statement().dialect().prefix(fields, this.alias());
    this.statement().group(fields);
    return this;
  }

  /**
   * Adds some having conditions to the query
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  having(conditions) {
    conditions = this.statement().dialect().prefix(conditions, this.alias());
    this.statement().having(conditions);
    return this;
  }

  /**
   * Adds some order by fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  order(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);
    fields = this.statement().dialect().prefix(fields, this.alias());
    this.statement().order(fields);
    return this;
  }

  /**
   * Sets page number.
   *
   * @param  integer page The page number
   * @return self
   */
  page(page)
  {
    this._page.page = page;
    return this;
  }

  /**
   * Sets offset value.
   *
   * @param  integer offset The offset value.
   * @return self
   */
  offset(offset)
  {
    this._page.offset = offset;
    return this;
  }

  /**
   * Sets limit value.
   *
   * @param  integer limit The number of results to limit or `0` for limit at all.
   * @return self
   */
  limit(limit)
  {
    this._page.limit = Number.parseInt(limit);
    return this;
  }

  /**
   * Applies a query handler
   *
   * @param  Closure  closure A closure.
   * @return Function         Returns `this`.
   */
  handler(closure) {
    if (typeof closure === 'function') {
      closure(this);
    }
    return this;
  }

  /**
   * Sets the relations to retrieve.
   *
   * @param  array  embed The relations to load with the query.
   * @return object        Returns `this`.
   */
  embed(embed, conditions) {
    if (!arguments.length) {
      return this._embed;
    }
    if (typeof embed === "string" && arguments.length === 2) {
      var mix = {};
      mix[embed] = conditions || [];
      embed = [mix];
    } else {
      embed = Array.isArray(embed) ? embed : [embed];
    }
    this._embed = this._embed.concat(embed);
    return this;
  }

  /**
   * Sets the conditionnal dependency over some relations.
   *
   * @param array The conditionnal dependency.
   */
  has(has, conditions) {
    if (!arguments.length) {
      return this._has;
    }
    if (typeof has === "string" && arguments.length === 2) {
      var mix = {};
      mix[has] = conditions || [];
      has = [mix];
    }
    this._has = this._has.concat(has)
    return this;
  }

  /**
   * Gets a unique alias for the query or a query's relation if `relpath` is set.
   *
   * @param  string path   A dotted relation name or for identifying the query's relation.
   * @param  object schema The corresponding schema to alias.
   * @return string        A string alias.
   */
  alias(path, schema) {
    if (arguments.length < 2) {
      path = path || '';
      if (this._aliases[path] !== undefined) {
        return this._aliases[path];
      } else {
        throw new Error("No alias has been defined for `'" + path + "'`.");
      }
    }

    var alias = schema.source();
    if (this._aliasCounter[alias] === undefined) {
      this._aliasCounter[alias] = 0;
      this._aliases[path] = alias;
    } else {
      alias = this._aliases[path] = alias + '__' + this._aliasCounter[alias]++;
    }
    this._schemas[alias] = schema;
    return alias;
  }

  /**
   * Applies the has conditions.
   */
  _applyHas() {
    var schema = this.schema();
    var tree = schema.treeify(this.has());
    this._applyJoins(this.schema(), tree, '', this.alias());
    var has = this.has();
    for (var value of has) {
      var key = Object.keys(value)[0];
      var conditions = value[key];
      this.where(conditions, this.alias(key));
    }
  }

  /**
   * Applies the limit range when applicable.
   */
  _applyLimit() {
    if (!this._page.limit) {
        return;
    }
    var offset;
    if (this._page.offset) {
      offset = this._page.offset;
    } else {
      var page = this._page.page ? this._page.page : 1;
      offset = (page - 1) * this._page.limit;
    }
    this.statement().limit(this._page.limit, offset);
  }

  /**
   * Applies joins.
   *
   * @param Object schema    The schema to perform joins on.
   * @param Array  tree      The tree of relations to join.
   * @param Array  basePath  The base relation path.
   * @param String aliasFrom The alias name of the from model.
   */
  _applyJoins(schema, tree, basePath, aliasFrom) {
    for (var key in tree) {
      var childs = tree[key];
      var rel = schema.relation(key);
      var path = basePath ? basePath + '.' + key : key;
      var to;

      if (rel.type() !== 'hasManyThrough') {
        to = this._join(path, rel, aliasFrom);
      } else {
        var name = rel.using();
        var nameThrough = rel.through();
        var pathThrough = path ? path + '.' + nameThrough : nameThrough;
        var from = rel.from();

        var relThrough = from.definition().relation(nameThrough);
        var aliasThrough = this._join(pathThrough, relThrough, aliasFrom);

        var modelThrough = relThrough.to();
        var relTo = modelThrough.definition().relation(name);
        to = this._join(path, relTo, aliasThrough);
      }

      if (childs && Object.keys(childs).length) {
        this._applyJoins(rel.to().definition(), childs, path, to);
      }
    }
  }

  /**
   * Set a query's join according a Relationship.
   *
   * @param  string path      The relation path.
   * @param  object rel       A Relationship instance.
   * @param  string fromAlias The "from" model alias.
   * @return string           The "to" model alias.
   */
  _join(path, rel, fromAlias) {
    if (this._aliases[path] !== undefined) {
      return this._aliases[path];
    }

    var schema = rel.to().definition();
    var source = schema.source();
    var toAlias = this.alias(path, schema);

    var table = {};
    table[source] = toAlias;

    this.statement().join(
      table,
      this._on(rel, fromAlias, toAlias),
      'LEFT'
    );
    return toAlias;
  }

  /**
   * Build the `ON` constraints from a `Relationship` instance.
   *
   * @param  object rel       A Relationship instance.
   * @param  string fromAlias The "from" model alias.
   * @param  string toAlias   The "to" model alias.
   * @return array             A constraints array.
   */
  _on(rel, fromAlias, toAlias) {
    if (rel.type() === 'hasManyThrough') {
      return [];
    }
    var keys = rel.keys();
    var fromField = Object.keys(keys)[0];
    var toField = keys[fromField];
    return { '=': [{ ':name': fromAlias + '.' + fromField },  { ':name': toAlias + '.' + toField }] };
  }
}

/**
 * Class dependencies.
 *
 * @var array
 */
Query._classes = {
  collector: Collector
};

export default Query;
<commit_msg>Fix typo.<commit_after>import co from 'co';
import { extend, merge } from 'extend-merge';
import { Model, Collector } from 'chaos-orm';

/**
 * The Query wrapper.
 */
class Query {

  /**
   * Gets/sets classes dependencies.
   *
   * @param  Object classes The classes dependencies to set or none to get it.
   * @return mixed          The classes dependencies.
   */
  static classes(classes) {
    if (arguments.length) {
      this._classes = extend({}, this._classes, classes);
    }
    return this._classes;
  }

  /**
   * Creates a new record object with default values.
   *
   * @param array config Possible options are:
   *                      - `'model'`  _Function_ : A model class.
   *                      - `'schema'` _Object_   : Alternatively a schema instance can be provided instead of the model.
   *                      - `'query'`  _Object_   : The query.
   */
  constructor(config) {
    var defaults = {
      model: undefined,
      schema: undefined,
      query: {}
    };
    config = extend({}, defaults, config);

    if (config.model) {
      this._model = config.model;
      this._schema = this._model.definition();
    } else {
      this._schema = config.schema;
    }

    /**
     * Count the number of identical aliases in a query for building unique aliases.
     *
     * @var Object
     */
    this._aliasCounter = {};

    /**
     * Map beetween relation pathsand corresponding aliases.
     *
     * @var Object
     */
    this._aliases = {};

    /**
     * Map beetween generated aliases and corresponding schema.
     *
     * @var Object
     */
    this._schemas = {};

    /**
     * The relations to include.
     *
     * @var Array
     */
    this._embed = [];

    /**
     * Some conditions over some relations.
     *
     * @var Array
     */
    this._has = [];

    /**
     * Pagination.
     *
     * @var Array
     */
    this._page = [];

    var schema = this.schema();

    /**
     * The select statement instance.
     *
     * @var Function
     */
    this._statement = schema.connection().dialect().statement('select');

    var source = schema.source();
    var from = {};
    from[source] = this.alias('', schema);
    this.statement().from(from);

    for (var key in config.query) {
      this[key](config.query[key]);
    }
  }

  /**
   * Gets the schema.
   *
   * @return Function Returns the schema.
   */
  schema() {
    if (!this._schema) {
      throw new Error("Error, missing schema for this query.");
    }
    return this._schema;
  }

  /**
   * Gets the model.
   *
   * @return Function Returns the model.
   */
  model() {
    return this._model;
  }

  /**
   * Gets the query statement.
   *
   * @return Function Returns a connection instance.
   */
  statement() {
    return this._statement;
  }

  /**
   * Executes the query and returns the result.
   *
   * @param  Object  Options The fetching options.
   * @return Promise         A Promise.
   */
  get(options) {
    return co(function*(){
      var defaults = {
        collector: undefined,
        return: 'entity'
      };
      options = extend({}, defaults, options);

      var classname = this.constructor.classes().collector;
      var collector = options.collector = options.collector ? options.collector : new classname();

      this._applyHas();
      this._applyLimit();

      var noFields = !this.statement().data('fields').length;
      if (noFields) {
        var star = {};
        star[this.alias()] = ['*'];
        this.statement().fields([star]);
      }

      var collection = [];
      var ret = options['return'];

      var schema = this.schema();
      var cursor = yield schema.connection().query(this.statement().toString());

      switch (ret) {
        case 'entity':
          var source = schema.source();
          var key = schema.key();

          var model = this.model();
          if (!model) {
            throw new Error("Missing model for this query, set `'return'` to `'object'` to get row data.");
          }

          collection = model.create([], {
            collector: collector,
            type: 'set',
            exists: true
          });

          for (var record of cursor) {
            var uuid = source + ':' + record[key];
            if (record[key] && collector.has(uuid)) {
              collection.push(collector.get(uuid));
            } else {
              collection.push(model.create(record, {
                collector: collector,
                exists: noFields ? true : null
              }));
            }
          }
          break;
        case 'array':
        case 'object':
          for (var record of cursor) {
            collection.push(extend({}, record));
          }
          break;
        default:
          throw new Error("Invalid `'" + options['return'] + "'` mode as `'return'` value");
          break;
      }
      return schema.embed(collection, this._embed, { fetchOptions: options });
    }.bind(this));
  }

  /**
   * Alias for `get()`
   *
   * @return object An iterator instance.
   */
  all(options) {
    return this.get(options);
  }

  /**
   * Executes the query and returns the first result only.
   *
   * @return object An entity instance.
   */
  first(options) {
    return co(function*() {
      var result = yield this.get(options);
      return Array.isArray(result) ? result[0] : result.get(0);
    }.bind(this));
  }

  /**
   * Executes the query and returns the count number.
   *
   * @return integer The number of rows in result.
   */
  count() {
    return co(function*() {
      var schema = this.schema();
      this.statement().fields([{':plain': 'COUNT(*)'}]);
      var cursor = yield schema.connection().query(this.statement().toString());
      var result = cursor.next();
      var key = Object.keys(result)[0]
      return Number.parseInt(result[key]);
    }.bind(this));
  }

  /**
   * Adds some fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  fields(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);

    var schema = this.schema();

    for (var value of fields) {
      if (typeof value === 'string' && schema.has(value)) {
        var aliased = {};
        aliased[this.alias()] = [value]
        this.statement().fields(aliased);
      } else {
        this.statement().fields(value);
      }
    }
    return this;
  }

  /**
   * Adds some where conditions to the query
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  where(conditions, alias) {
    var conditions = this.statement().dialect().prefix(conditions, alias ? alias : this.alias(), false);
    this.statement().where(conditions);
    return this;
  }

  /**
   * Alias for `where()`.
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  conditions(conditions) {
    return this.where(conditions);
  }

  /**
   * Adds some group by fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  group(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);
    fields = this.statement().dialect().prefix(fields, this.alias());
    this.statement().group(fields);
    return this;
  }

  /**
   * Adds some having conditions to the query
   *
   * @param  mixed    conditions The conditions for this query.
   * @return Function            Returns `this`.
   */
  having(conditions) {
    conditions = this.statement().dialect().prefix(conditions, this.alias());
    this.statement().having(conditions);
    return this;
  }

  /**
   * Adds some order by fields to the query
   *
   * @param  mixed    fields The fields.
   * @return Function        Returns `this`.
   */
  order(fields) {
    fields = Array.isArray(fields) && arguments.length === 1 ? fields : Array.prototype.slice.call(arguments);
    fields = this.statement().dialect().prefix(fields, this.alias());
    this.statement().order(fields);
    return this;
  }

  /**
   * Sets page number.
   *
   * @param  integer page The page number
   * @return self
   */
  page(page)
  {
    this._page.page = page;
    return this;
  }

  /**
   * Sets offset value.
   *
   * @param  integer offset The offset value.
   * @return self
   */
  offset(offset)
  {
    this._page.offset = offset;
    return this;
  }

  /**
   * Sets limit value.
   *
   * @param  integer limit The number of results to limit or `0` for limit at all.
   * @return self
   */
  limit(limit)
  {
    this._page.limit = Number.parseInt(limit);
    return this;
  }

  /**
   * Applies a query handler
   *
   * @param  Closure  closure A closure.
   * @return Function         Returns `this`.
   */
  handler(closure) {
    if (typeof closure === 'function') {
      closure(this);
    }
    return this;
  }

  /**
   * Sets the relations to retrieve.
   *
   * @param  array  embed The relations to load with the query.
   * @return object        Returns `this`.
   */
  embed(embed, conditions) {
    if (!arguments.length) {
      return this._embed;
    }
    if (typeof embed === "string" && arguments.length === 2) {
      var mix = {};
      mix[embed] = conditions || [];
      embed = [mix];
    } else {
      embed = Array.isArray(embed) ? embed : [embed];
    }
    this._embed = this._embed.concat(embed);
    return this;
  }

  /**
   * Sets the conditionnal dependency over some relations.
   *
   * @param array The conditionnal dependency.
   */
  has(has, conditions) {
    if (!arguments.length) {
      return this._has;
    }
    if (typeof has === "string" && arguments.length === 2) {
      var mix = {};
      mix[has] = conditions || [];
      has = [mix];
    }
    this._has = this._has.concat(has)
    return this;
  }

  /**
   * Gets a unique alias for the query or a query's relation if `relpath` is set.
   *
   * @param  string path   A dotted relation name or for identifying the query's relation.
   * @param  object schema The corresponding schema to alias.
   * @return string        A string alias.
   */
  alias(path, schema) {
    if (arguments.length < 2) {
      path = path || '';
      if (this._aliases[path] !== undefined) {
        return this._aliases[path];
      } else {
        throw new Error("No alias has been defined for `'" + path + "'`.");
      }
    }

    var alias = schema.source();
    if (this._aliasCounter[alias] === undefined) {
      this._aliasCounter[alias] = 0;
      this._aliases[path] = alias;
    } else {
      alias = this._aliases[path] = alias + '__' + this._aliasCounter[alias]++;
    }
    this._schemas[alias] = schema;
    return alias;
  }

  /**
   * Applies the has conditions.
   */
  _applyHas() {
    var schema = this.schema();
    var tree = schema.treeify(this.has());
    this._applyJoins(this.schema(), tree, '', this.alias());
    var has = this.has();
    for (var value of has) {
      var key = Object.keys(value)[0];
      var conditions = value[key];
      this.where(conditions, this.alias(key));
    }
  }

  /**
   * Applies the limit range when applicable.
   */
  _applyLimit() {
    if (!this._page.limit) {
        return;
    }
    var offset;
    if (this._page.offset) {
      offset = this._page.offset;
    } else {
      var page = this._page.page ? this._page.page : 1;
      offset = (page - 1) * this._page.limit;
    }
    this.statement().limit(this._page.limit, offset);
  }

  /**
   * Applies joins.
   *
   * @param Object schema    The schema to perform joins on.
   * @param Array  tree      The tree of relations to join.
   * @param Array  basePath  The base relation path.
   * @param String aliasFrom The alias name of the from model.
   */
  _applyJoins(schema, tree, basePath, aliasFrom) {
    for (var key in tree) {
      var childs = tree[key];
      var rel = schema.relation(key);
      var path = basePath ? basePath + '.' + key : key;
      var to;

      if (rel.type() !== 'hasManyThrough') {
        to = this._join(path, rel, aliasFrom);
      } else {
        var name = rel.using();
        var nameThrough = rel.through();
        var pathThrough = path ? path + '.' + nameThrough : nameThrough;
        var from = rel.from();

        var relThrough = from.definition().relation(nameThrough);
        var aliasThrough = this._join(pathThrough, relThrough, aliasFrom);

        var modelThrough = relThrough.to();
        var relTo = modelThrough.definition().relation(name);
        to = this._join(path, relTo, aliasThrough);
      }

      if (childs && Object.keys(childs).length) {
        this._applyJoins(rel.to().definition(), childs, path, to);
      }
    }
  }

  /**
   * Set a query's join according a Relationship.
   *
   * @param  string path      The relation path.
   * @param  object rel       A Relationship instance.
   * @param  string fromAlias The "from" model alias.
   * @return string           The "to" model alias.
   */
  _join(path, rel, fromAlias) {
    if (this._aliases[path] !== undefined) {
      return this._aliases[path];
    }

    var schema = rel.to().definition();
    var source = schema.source();
    var toAlias = this.alias(path, schema);

    var table = {};
    table[source] = toAlias;

    this.statement().join(
      table,
      this._on(rel, fromAlias, toAlias),
      'LEFT'
    );
    return toAlias;
  }

  /**
   * Build the `ON` constraints from a `Relationship` instance.
   *
   * @param  object rel       A Relationship instance.
   * @param  string fromAlias The "from" model alias.
   * @param  string toAlias   The "to" model alias.
   * @return array             A constraints array.
   */
  _on(rel, fromAlias, toAlias) {
    if (rel.type() === 'hasManyThrough') {
      return [];
    }
    var keys = rel.keys();
    var fromField = Object.keys(keys)[0];
    var toField = keys[fromField];
    return { '=': [{ ':name': fromAlias + '.' + fromField },  { ':name': toAlias + '.' + toField }] };
  }
}

/**
 * Class dependencies.
 *
 * @var array
 */
Query._classes = {
  collector: Collector
};

export default Query;
<|endoftext|>


<commit_before>const Parse = require('parse/node');
const Promise = require('bluebird');
const { flatten, logger } = require('./util');

function batchQuery(where, batchSize, count, order = 'objectId') {
  const items = [];
  for (let skip = 0; skip < count; skip += batchSize) {
    if (skip > count) {
      skip = count;
    }

    items.push({
      where,
      limit: batchSize,
      skip,
      order,
    });
  }
  return items;
}

function sliceArray(array, size) {
  const results = [];
  while (array.length > 0) {
    results.push(array.slice(0, size));
    array = array.slice(size);
  }
  return results;
}

function getObjectIds(where, batchSize, firstElement) {
  const installationsQ = Parse.Query.fromJSON('_Installation', {
    where,
  });
  installationsQ.exists('deviceToken');
  installationsQ.limit(batchSize);
  installationsQ.select([ 'objectId' ]);
  installationsQ.ascending('objectId');
  if (firstElement) {
    installationsQ.greaterThan('objectId', firstElement);
  }
  return installationsQ.find({ useMasterKey: true });
}

function smartBatch(where, batchSize, firstElement, objects = []) {
  return getObjectIds(where, batchSize, firstElement).then((results) => {
    objects.push(results.map((res) => res.id));
    const last = results[results.length-1].id;
    console.log('Done: '+ results.length + ' ' +  last); // eslint-disable-line
    if (results.length === batchSize) {
      return smartBatch(where, batchSize, last, objects);
    }
  }).then(() => {
    if (objects.length > 0) {
      logger.info(`Creating about ${objects.length * batchSize}`);
    }
    return objects.reduce((memo, array) => {
      return memo.concat(sliceArray(array, 100));
    }, []);
  });
}

function batchPushWorkItem(pushWorkItem, batchSize = 100, querySize = 10000) {
  return smartBatch(pushWorkItem.query.where, querySize).then((slices) => {
    return slices.reduce((memo, array) => {
      return memo.concat(sliceArray(array, batchSize));
    }, []).map((slice) => {
      const batch = { objectId: { $in: slice } };
      return Object.assign({}, pushWorkItem, { query: { where: batch } });
    });
  });
}

function getScheduledPushes() {
  const pushStatusesQ = new Parse.Query('_PushStatus');
  pushStatusesQ.containedIn('status', [ 'scheduled' ]);

  return Promise.resolve(pushStatusesQ.count({ useMasterKey: true }))
    .then((count) =>
      batchQuery(pushStatusesQ.toJSON().where, 1000, count)
        .map((batch) => Parse.Query.fromJSON('_PushStatus', batch)))

    .mapSeries((query) => Promise.resolve(query.find({ useMasterKey: true }))
      .filter((pushStatus) => {
        // Filter out immediate pushes which are currently running
        if (pushStatus.get('status') === 'running' && !pushStatus.has('sentPerUTCOffset')) {
          logger.debug('Filtered out pushStatus', {
            type: 'immediate',
            pushStatus: pushStatus.toJSON(),
          });
          return false;
        }

        return true;
      }
    ))
    .then(flatten)
    .tap((pushStatuses) => {
      logger.info(`Found ${pushStatuses.length} potential pushes`, {
        pushStatuses: pushStatuses.map((p) => p.toJSON()),
      });
    });
}

function getPushesByCampaign(campaign) {
  const pushes = campaign.relation('pushes');
  return pushes.query()
    .descending('createdAt')
    .find({ useMasterKey: true });
}

function getActiveCampaigns() {
  logger.debug('Finding active campaigns');
  const campaignsQ = new Parse.Query('PushCampaign');
  return campaignsQ.equalTo('status', 'active')
    .find({ useMasterKey: true });
}

module.exports = {
  getActiveCampaigns,
  getScheduledPushes,
  getPushesByCampaign,
  batchQuery,
  batchPushWorkItem,
  smartBatch,
};
<commit_msg>Break when no results are found<commit_after>const Parse = require('parse/node');
const Promise = require('bluebird');
const { flatten, logger } = require('./util');

function batchQuery(where, batchSize, count, order = 'objectId') {
  const items = [];
  for (let skip = 0; skip < count; skip += batchSize) {
    if (skip > count) {
      skip = count;
    }

    items.push({
      where,
      limit: batchSize,
      skip,
      order,
    });
  }
  return items;
}

function sliceArray(array, size) {
  const results = [];
  while (array.length > 0) {
    results.push(array.slice(0, size));
    array = array.slice(size);
  }
  return results;
}

function getObjectIds(where, batchSize, firstElement) {
  const installationsQ = Parse.Query.fromJSON('_Installation', {
    where,
  });
  installationsQ.exists('deviceToken');
  installationsQ.limit(batchSize);
  installationsQ.select([ 'objectId' ]);
  installationsQ.ascending('objectId');
  if (firstElement) {
    installationsQ.greaterThan('objectId', firstElement);
  }
  return installationsQ.find({ useMasterKey: true });
}

function smartBatch(where, batchSize, firstElement, objects = []) {
  return getObjectIds(where, batchSize, firstElement).then((results) => {
    objects.push(results.map((res) => res.id));
    if (results.length === 0) {
      console.log('No results found...'); // eslint-disable-line
      return;
    }
    const last = results[results.length-1].id;
    console.log('Done: '+ results.length + ' ' +  last); // eslint-disable-line
    if (results.length === batchSize) {
      return smartBatch(where, batchSize, last, objects);
    }
  }).then(() => {
    if (objects.length > 0) {
      logger.info(`Creating about ${objects.length * batchSize}`);
    }
    return objects.reduce((memo, array) => {
      return memo.concat(sliceArray(array, 100));
    }, []);
  });
}

function batchPushWorkItem(pushWorkItem, batchSize = 100, querySize = 10000) {
  return smartBatch(pushWorkItem.query.where, querySize).then((slices) => {
    return slices.reduce((memo, array) => {
      return memo.concat(sliceArray(array, batchSize));
    }, []).map((slice) => {
      const batch = { objectId: { $in: slice } };
      return Object.assign({}, pushWorkItem, { query: { where: batch } });
    });
  });
}

function getScheduledPushes() {
  const pushStatusesQ = new Parse.Query('_PushStatus');
  pushStatusesQ.containedIn('status', [ 'scheduled' ]);

  return Promise.resolve(pushStatusesQ.count({ useMasterKey: true }))
    .then((count) =>
      batchQuery(pushStatusesQ.toJSON().where, 1000, count)
        .map((batch) => Parse.Query.fromJSON('_PushStatus', batch)))

    .mapSeries((query) => Promise.resolve(query.find({ useMasterKey: true }))
      .filter((pushStatus) => {
        // Filter out immediate pushes which are currently running
        if (pushStatus.get('status') === 'running' && !pushStatus.has('sentPerUTCOffset')) {
          logger.debug('Filtered out pushStatus', {
            type: 'immediate',
            pushStatus: pushStatus.toJSON(),
          });
          return false;
        }

        return true;
      }
    ))
    .then(flatten)
    .tap((pushStatuses) => {
      logger.info(`Found ${pushStatuses.length} potential pushes`, {
        pushStatuses: pushStatuses.map((p) => p.toJSON()),
      });
    });
}

function getPushesByCampaign(campaign) {
  const pushes = campaign.relation('pushes');
  return pushes.query()
    .descending('createdAt')
    .find({ useMasterKey: true });
}

function getActiveCampaigns() {
  logger.debug('Finding active campaigns');
  const campaignsQ = new Parse.Query('PushCampaign');
  return campaignsQ.equalTo('status', 'active')
    .find({ useMasterKey: true });
}

module.exports = {
  getActiveCampaigns,
  getScheduledPushes,
  getPushesByCampaign,
  batchQuery,
  batchPushWorkItem,
  smartBatch,
};
<|endoftext|>