<commit_before>// OEIS is a singleton object that provides convenient functions for performing requests to the OEIS database.
// Properties:
//   proxy
//   endpoint
//   lastRequest
//   language
// Functions:
//   searchByID(id, format, callback)
//   searchByTerms(terms, format, callback)
//   searchByTermsAndStart(terms, start, format, callback)
//   searchByQuery(queryString, format, callback)
//   searchByQueryAndStart(queryString, start, format, callback)
//   getGraphForSequenceID(id, format, callback)
//   createCORSRequest(method, url)
//   doRequest(URL, format, callback)

var OEIS = new Object();

// OEIS.proxy is a hack to get around browsers' CORS security functionality. This will be removed once most of the class's functionality is implemented and tested.
OEIS.proxy = "http://crossorigin.me/";
OEIS.endpoint = OEIS.proxy + "http://oeis.org/";
// OEIS.lastRequest stores the response text of the last request to OEIS
OEIS.lastRequest = "";
// language that the search results should be in. defaults to "english"
OEIS.language = "english";

// Searches the OEIS by the sequence's ID (e.g. A000045)
// id: The ID of the sequence. Must be a string: preceded by an 'A' and have six digits OR preceded by an 'M' or 'N' and have four digits. Note that if the ID is not in the correct format, OEIS will treat it as a general search query and may return more than one result. Examples: "A000045", "M0692", "N0256"
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json", data if the format specified was "png", or text otherwise.
OEIS.searchByID = function (id, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + "id:" + id + "&" + "fmt=" + format;
    OEIS.doRequest(URL, format, callback);
};

// Searches the OEIS by terms in a sequence (e.g. 1,1,2,3,5) with start=0.
// terms: an array of the terms
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByTerms = function (terms, format, callback) {
    OEIS.searchByTermsAndStart(terms, 0, format, callback);
}

// Searches the OEIS by terms in a sequence (e.g. 1,1,2,3,5) and a start.
// terms: an array of the terms
// start: OEIS returns at most 10 results at a time, so start is used to adjust which results are retrieved. Example: start=0 gets the first 10 search results, start=10 will get the next 10 search results, etc.
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByTermsAndStart = function (terms, start, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + terms.toString() + "&" + "fmt=" + format + "&" + "start=" + start;
    OEIS.doRequest(URL, format, callback);
}

// Searches the OEIS by a query string (e.g. '2,3,6,16 "symmetric group" author:Stanley') and start=0
// queryString: A string consisting of a query similar to what one might type in the search bar on the OEIS website. This string will be URI encoded before the request is sent, so the string really should be as one would type on the website. Example: '2,3,6,16 "symmetric group" author:Stanley'
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByQuery = function (queryString, format, callback) {
    OEIS.searchByQueryAndStart(queryString, 0, format, callback);
};

// Searches the OEIS by a query string (e.g. '2,3,6,16 "symmetric group" author:Stanley') and a start
// queryString: A string consisting of a query similar to what one might type in the search bar on the OEIS website. This string will be URI encoded before the request is sent, so the string really should be as one would type on the website. Example: '2,3,6,16 "symmetric group" author:Stanley'
// start: OEIS returns at most 10 results at a time, so start is used to adjust which results are retrieved. Example: start=0 gets the first 10 search results, start=10 will get the next 10 search results, etc.
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByQueryAndStart = function (queryString, start, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + encodeURIComponent(queryString)+ "&" + "fmt=" + format + "&" + "start=" + start;
    OEIS.doRequest(URL, format, callback);
};

// Retrieves the graph for a sequence by the sequence's ID.
// id: A string containing the ID of the sequence. Example: "A000045".
// format: "png"
// callback: a function that is called with the search results passed as an argument. The argument is returned as data since the format is PNG.
OEIS.getGraphForSequenceID = function (id, format, callback) {
    if (!format) {
        format = "png";
    }
    URL = OEIS.endpoint + id + "/graph?png=1";
    OEIS.doRequest(URL, format, callback);
}

// Based heavily on code found on www.html5rocks.com by
// Monsur Hossain.
// https://www.html5rocks.com/en/tutorials/cors/
// Convenience method that creates and returns an XMLHttpRequest. Not meant for public use. For making requests, please use the OEIS.searchBy() family of functions.
OEIS.createCORSRequest = function (method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {

        // Check if the XMLHttpRequest object has a "withCredentials" property.
        // "withCredentials" only exists on XMLHTTPRequest2 objects.
        xhr.open(method, url, true);

    } else if (typeof XDomainRequest != "undefined") {

        // Otherwise, check if XDomainRequest.
        // XDomainRequest only exists in IE, and is IE's way of making CORS requests.
        xhr = new XDomainRequest();
        xhr.open(method, url);

    } else {

        // Otherwise, CORS is not supported by the browser.
        xhr = null;

    }
    return xhr;
};

// Convenience method that executes an XMLHttpRequest. Not meant for public use. For making requests, please use OEIS.searchBy() family of functions.
//TODO: add xhr.onerror
//TODO: add xhr.ontimeout
OEIS.doRequest = function (URL, format, callback) {
    var xhr = OEIS.createCORSRequest("GET", URL);
    if (!xhr) {
        throw new Error('CORS not supported');
    }
    // xhr.onload is called after a successful request.
    xhr.onload = function () {
        OEIS.lastRequest = xhr.responseText;
        if (callback) {
            // Check if format is set in order to determine in which format to return the response.
            if (format) {
                // check if format has toLowerCase and trim methods (i.e. check if format is a string)
                if (format.toLowerCase && format.trim) {
                    cleanFormat = format.toLowerCase().trim();
                    if (cleanFormat === "json") {
                        callback(JSON.parse(xhr.responseText));
                    }
                    else if (cleanFormat === "text") {
                        callback(xhr.responseText);
                    }
                    else if (cleanFormat === "png") {
                        callback(xhr.response);
                    }
                }
            }
            else {
                callback(xhr.responseText);
            }
        }
    };
    xhr.send();
};
<commit_msg>fixed comments for searchByID<commit_after>// OEIS is a singleton object that provides convenient functions for performing requests to the OEIS database.
// Properties:
//   proxy
//   endpoint
//   lastRequest
//   language
// Functions:
//   searchByID(id, format, callback)
//   searchByTerms(terms, format, callback)
//   searchByTermsAndStart(terms, start, format, callback)
//   searchByQuery(queryString, format, callback)
//   searchByQueryAndStart(queryString, start, format, callback)
//   getGraphForSequenceID(id, format, callback)
//   createCORSRequest(method, url)
//   doRequest(URL, format, callback)

var OEIS = new Object();

// OEIS.proxy is a hack to get around browsers' CORS security functionality. This will be removed once most of the class's functionality is implemented and tested.
OEIS.proxy = "http://crossorigin.me/";
OEIS.endpoint = OEIS.proxy + "http://oeis.org/";
// OEIS.lastRequest stores the response text of the last request to OEIS
OEIS.lastRequest = "";
// language that the search results should be in. defaults to "english"
OEIS.language = "english";

// Searches the OEIS by the sequence's ID (e.g. A000045)
// id: The ID of the sequence. Must be a string: preceded by an 'A' and have six digits OR preceded by an 'M' or 'N' and have four digits. Note that if the ID is not in the correct format, OEIS will treat it as a general search query and may return more than one result. Examples: "A000045", "M0692", "N0256"
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByID = function (id, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + "id:" + id + "&" + "fmt=" + format;
    OEIS.doRequest(URL, format, callback);
};

// Searches the OEIS by terms in a sequence (e.g. 1,1,2,3,5) with start=0.
// terms: an array of the terms
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByTerms = function (terms, format, callback) {
    OEIS.searchByTermsAndStart(terms, 0, format, callback);
}

// Searches the OEIS by terms in a sequence (e.g. 1,1,2,3,5) and a start.
// terms: an array of the terms
// start: OEIS returns at most 10 results at a time, so start is used to adjust which results are retrieved. Example: start=0 gets the first 10 search results, start=10 will get the next 10 search results, etc.
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByTermsAndStart = function (terms, start, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + terms.toString() + "&" + "fmt=" + format + "&" + "start=" + start;
    OEIS.doRequest(URL, format, callback);
}

// Searches the OEIS by a query string (e.g. '2,3,6,16 "symmetric group" author:Stanley') and start=0
// queryString: A string consisting of a query similar to what one might type in the search bar on the OEIS website. This string will be URI encoded before the request is sent, so the string really should be as one would type on the website. Example: '2,3,6,16 "symmetric group" author:Stanley'
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByQuery = function (queryString, format, callback) {
    OEIS.searchByQueryAndStart(queryString, 0, format, callback);
};

// Searches the OEIS by a query string (e.g. '2,3,6,16 "symmetric group" author:Stanley') and a start
// queryString: A string consisting of a query similar to what one might type in the search bar on the OEIS website. This string will be URI encoded before the request is sent, so the string really should be as one would type on the website. Example: '2,3,6,16 "symmetric group" author:Stanley'
// start: OEIS returns at most 10 results at a time, so start is used to adjust which results are retrieved. Example: start=0 gets the first 10 search results, start=10 will get the next 10 search results, etc.
// format: "json" or "text"
// callback: a function that is called with the search results passed as an argument. The argument is either a JavaScript object if the format specified was "json" or text otherwise.
OEIS.searchByQueryAndStart = function (queryString, start, format, callback) {
    if (!format) {
        format = "html";
    }
    URL = OEIS.endpoint + "search?" + "language=" + OEIS.language + "&" + "q=" + encodeURIComponent(queryString)+ "&" + "fmt=" + format + "&" + "start=" + start;
    OEIS.doRequest(URL, format, callback);
};

// Retrieves the graph for a sequence by the sequence's ID.
// id: A string containing the ID of the sequence. Example: "A000045".
// format: "png"
// callback: a function that is called with the search results passed as an argument. The argument is returned as data since the format is PNG.
OEIS.getGraphForSequenceID = function (id, format, callback) {
    if (!format) {
        format = "png";
    }
    URL = OEIS.endpoint + id + "/graph?png=1";
    OEIS.doRequest(URL, format, callback);
}

// Based heavily on code found on www.html5rocks.com by
// Monsur Hossain.
// https://www.html5rocks.com/en/tutorials/cors/
// Convenience method that creates and returns an XMLHttpRequest. Not meant for public use. For making requests, please use the OEIS.searchBy() family of functions.
OEIS.createCORSRequest = function (method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {

        // Check if the XMLHttpRequest object has a "withCredentials" property.
        // "withCredentials" only exists on XMLHTTPRequest2 objects.
        xhr.open(method, url, true);

    } else if (typeof XDomainRequest != "undefined") {

        // Otherwise, check if XDomainRequest.
        // XDomainRequest only exists in IE, and is IE's way of making CORS requests.
        xhr = new XDomainRequest();
        xhr.open(method, url);

    } else {

        // Otherwise, CORS is not supported by the browser.
        xhr = null;

    }
    return xhr;
};

// Convenience method that executes an XMLHttpRequest. Not meant for public use. For making requests, please use OEIS.searchBy() family of functions.
//TODO: add xhr.onerror
//TODO: add xhr.ontimeout
OEIS.doRequest = function (URL, format, callback) {
    var xhr = OEIS.createCORSRequest("GET", URL);
    if (!xhr) {
        throw new Error('CORS not supported');
    }
    // xhr.onload is called after a successful request.
    xhr.onload = function () {
        OEIS.lastRequest = xhr.responseText;
        if (callback) {
            // Check if format is set in order to determine in which format to return the response.
            if (format) {
                // check if format has toLowerCase and trim methods (i.e. check if format is a string)
                if (format.toLowerCase && format.trim) {
                    cleanFormat = format.toLowerCase().trim();
                    if (cleanFormat === "json") {
                        callback(JSON.parse(xhr.responseText));
                    }
                    else if (cleanFormat === "text") {
                        callback(xhr.responseText);
                    }
                    else if (cleanFormat === "png") {
                        callback(xhr.response);
                    }
                }
            }
            else {
                callback(xhr.responseText);
            }
        }
    };
    xhr.send();
};
<|endoftext|>


<commit_before><commit_msg>[updated] view property in page<commit_after><|endoftext|>


<commit_before><commit_msg>Fix some compile issues, data format errors in src/plug.js<commit_after><|endoftext|>


<commit_before>function vorbis_look_residue0(p) {
  p = p||{};

  //   vorbis_info_residue0 *info;

  //   int         parts;
  //   int         stages;
  //   codebook   *fullbooks;
  //   codebook   *phrasebook;
  //   codebook ***partbooks;

  //   int         partvals;
  //   int       **decodemap;

  //   long      postbits;
  //   long      phrasebits;
  //   long      frames;

  // #if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
  //   int        train_seq;
  //   long      *training_data[8][64];
  //   float      training_max[8][64];
  //   float      training_min[8][64];
  //   float     tmin;
  //   float     tmax;
  //   int       submap;
  // #endif

  p.info = null;
  p.parts = 0;
  p.stages = 0;
  p.fullbooks = null;
  p.phrasebook = null;
  p.partbooks = null;
  p.partvals = 0;
  p.decodemap = null;
  p.postbits = 0;
  p.phrasebits = 0;
  p.frames = 0;
  p.__name = "vorbis_look_residue0";

  return p;
}

function res0_free_info(i) {
  NOT_IMPLEMENTED();
}

function res0_free_look(i) {
  NOT_IMPLEMENTED();
}

function res0_pack(vr, opb){
  NOT_IMPLEMENTED();
}

/* vorbis_info is for range checking */
function res0_unpack(vi, opb) {
  var j,acc=0;
  var info=vorbis_info_residue0();
  var ci=vi.codec_setup;
  var cascade,cflag,c,book,entries,dim,partvals;

  info.begin=oggpack_read(opb,24);
  info.end=oggpack_read(opb,24);
  info.grouping=oggpack_read(opb,24)+1;
  info.partitions=oggpack_read(opb,6)+1;
  info.groupbook=oggpack_read(opb,8);

  err_out:while(1){
    /* check for premature EOP */
    if(info.groupbook<0)break err_out;

    for(j=0;j<info.partitions;j++){
      cascade=oggpack_read(opb,3);
      cflag=oggpack_read(opb,1);
      if(cflag<0) break err_out;
      if(cflag){
        c=oggpack_read(opb,5);
        if(c<0) break err_out;
        cascade|=(c<<3);
      }
      info.secondstages[j]=cascade;

      acc+=icount(cascade);
    }
    for(j=0;j<acc;j++){
      book=oggpack_read(opb,8);
      if(book<0) break err_out;
      info.booklist[j]=book;
    }

    if(info.groupbook>=ci.books)break err_out;
    for(j=0;j<acc;j++){
      if(info.booklist[j]>=ci.books)break err_out;
      if(ci.book_param[info.booklist[j]].maptype===0)break err_out;
    }

    /* verify the phrasebook is not specifying an impossible or
       inconsistent partitioning scheme. */
    /* modify the phrasebook ranging check from r16327; an early beta
       encoder had a bug where it used an oversized phrasebook by
       accident.  These files should continue to be playable, but don't
       allow an exploit */
    {
      entries = ci.book_param[info.groupbook].entries;
      dim = ci.book_param[info.groupbook].dim;
      partvals = 1;
      if (dim<1) break err_out;
      while(dim>0){
        partvals *= info.partitions;
        if(partvals > entries) break err_out;
        dim--;
      }
      info.partvals = partvals;
    }

    return(info);
  }

  // errout:
  res0_free_info(info);
  return(NULL);
}

function res0_look(vd, vr) {
  var info=vr;
  var look=vorbis_look_residue0();
  var ci=vd.vi.codec_setup;

  var j,k,acc=0;
  var dim;
  var maxstage=0;
  var stages,val,mult,deco;

  look.info=info;

  look.parts=info.partitions;
  look.fullbooks=ci.fullbooks;
  look.phrasebook=ci.fullbooks[info.groupbook];
  dim=look.phrasebook.dim;

  look.partbooks=calloc(look.parts,[]);

  for(j=0;j<look.parts;j++){
    stages=ilog(info.secondstages[j]);
    if(stages){
      if(stages>maxstage)maxstage=stages;
      look.partbooks[j]=calloc(stages,codebook);
      for(k=0;k<stages;k++)
        if(info.secondstages[j]&(1<<k)){
          look.partbooks[j][k]=ci.fullbooks[info.booklist[acc++]];
        }
    }
  }

  look.partvals=1;
  for(j=0;j<dim;j++)
    look.partvals*=look.parts;

  look.stages=maxstage;
  look.decodemap=calloc(look.partvals,[]);
  for(j=0;j<look.partvals;j++){
    val=j;
    mult=int(look.partvals/look.parts);
    look.decodemap[j]=calloc(dim,int16);
    for(k=0;k<dim;k++){
      deco=int(val/mult);
      val-=deco*mult;
      mult=int(mult/look.parts);
      look.decodemap[j][k]=deco;
    }
  }
  return(look);
}

/* break an abstraction and copy some code for performance purposes */
function local_book_besterror(book, a) {
  NOT_IMPLEMENTED();
}

function _encodepart(opb, vec, n, book, acc) {
  NOT_IMPLEMENTED();
}

function _01class(vb, vl, _in, ch) {
  NOT_IMPLEMENTED();
}

/* designed for stereo or other modes where the partition size is an
   integer multiple of the number of channels encoded in the current
   submap */
function _2class(vb, vl, _in, ch) {
  NOT_IMPLEMENTED();
}

function _01forward(opb, vb, vl, _in, ch, partword, encode, submap) {
  NOT_IMPLEMENTED();
}

/* a truncated packet here just means 'stop working'; it's not an error */
function _01inverse(vb, vl, _in, ch, decodepart) {
  NOT_IMPLEMENTED();
}

function res0_inverse(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

function res1_forward(opb, vb, vl, _in, nonzero, ch, partword, submap) {
  NOT_IMPLEMENTED();
}

function res1_class(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

function res1_inverse(vb, vl, _in, nonzero, ch) {
  var i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      _in[used++]=_in[i];
  if(used)
    return(_01inverse(vb,vl,_in,used,vorbis_book_decodev_add));
  else
    return(0);
}

function res2_class(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

/* res2 is slightly more different; all the channels are interleaved
   into a single vector and encoded. */
function res2_forward(opb, vb, vl, _in, nonzero, ch, partword, submap) {
  NOT_IMPLEMENTED();
}

/* duplicate code here as speed is somewhat more important */
function res2_inverse(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

var residue0_exportbundle = vorbis_func_residue();
set_kv(residue0_exportbundle, {
  pack     : null,
  unpack   : res0_unpack,
  look     : res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass    : null,
  forward  : null,
  inverse  : res0_inverse
});

var residue1_exportbundle = vorbis_func_residue();
set_kv(residue1_exportbundle, {
  pack: res0_pack,
  unpack: res0_unpack,
  look: res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass: res1_class,
  forward: res1_forward,
  inverse: res1_inverse
});

var residue2_exportbundle = vorbis_func_residue();
set_kv(residue2_exportbundle, {
  pack     : res0_pack,
  unpack   : res0_unpack,
  look     : res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass    : res2_class,
  forward  : res2_forward,
  inverse  : res2_inverse
});

/* moved from:registry.js (latedef) */
var _residue_P = [
  residue0_exportbundle,
  residue1_exportbundle,
  residue2_exportbundle
];
<commit_msg>added: _01inverse<commit_after>function vorbis_look_residue0(p) {
  p = p||{};

  //   vorbis_info_residue0 *info;

  //   int         parts;
  //   int         stages;
  //   codebook   *fullbooks;
  //   codebook   *phrasebook;
  //   codebook ***partbooks;

  //   int         partvals;
  //   int       **decodemap;

  //   long      postbits;
  //   long      phrasebits;
  //   long      frames;

  // #if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
  //   int        train_seq;
  //   long      *training_data[8][64];
  //   float      training_max[8][64];
  //   float      training_min[8][64];
  //   float     tmin;
  //   float     tmax;
  //   int       submap;
  // #endif

  p.info = null;
  p.parts = 0;
  p.stages = 0;
  p.fullbooks = null;
  p.phrasebook = null;
  p.partbooks = null;
  p.partvals = 0;
  p.decodemap = null;
  p.postbits = 0;
  p.phrasebits = 0;
  p.frames = 0;
  p.__name = "vorbis_look_residue0";

  return p;
}

function res0_free_info(i) {
  NOT_IMPLEMENTED();
}

function res0_free_look(i) {
  NOT_IMPLEMENTED();
}

function res0_pack(vr, opb){
  NOT_IMPLEMENTED();
}

/* vorbis_info is for range checking */
function res0_unpack(vi, opb) {
  var j,acc=0;
  var info=vorbis_info_residue0();
  var ci=vi.codec_setup;
  var cascade,cflag,c,book,entries,dim,partvals;

  info.begin=oggpack_read(opb,24);
  info.end=oggpack_read(opb,24);
  info.grouping=oggpack_read(opb,24)+1;
  info.partitions=oggpack_read(opb,6)+1;
  info.groupbook=oggpack_read(opb,8);

  err_out:while(1){
    /* check for premature EOP */
    if(info.groupbook<0)break err_out;

    for(j=0;j<info.partitions;j++){
      cascade=oggpack_read(opb,3);
      cflag=oggpack_read(opb,1);
      if(cflag<0) break err_out;
      if(cflag){
        c=oggpack_read(opb,5);
        if(c<0) break err_out;
        cascade|=(c<<3);
      }
      info.secondstages[j]=cascade;

      acc+=icount(cascade);
    }
    for(j=0;j<acc;j++){
      book=oggpack_read(opb,8);
      if(book<0) break err_out;
      info.booklist[j]=book;
    }

    if(info.groupbook>=ci.books)break err_out;
    for(j=0;j<acc;j++){
      if(info.booklist[j]>=ci.books)break err_out;
      if(ci.book_param[info.booklist[j]].maptype===0)break err_out;
    }

    /* verify the phrasebook is not specifying an impossible or
       inconsistent partitioning scheme. */
    /* modify the phrasebook ranging check from r16327; an early beta
       encoder had a bug where it used an oversized phrasebook by
       accident.  These files should continue to be playable, but don't
       allow an exploit */
    {
      entries = ci.book_param[info.groupbook].entries;
      dim = ci.book_param[info.groupbook].dim;
      partvals = 1;
      if (dim<1) break err_out;
      while(dim>0){
        partvals *= info.partitions;
        if(partvals > entries) break err_out;
        dim--;
      }
      info.partvals = partvals;
    }

    return(info);
  }

  // errout:
  res0_free_info(info);
  return(NULL);
}

function res0_look(vd, vr) {
  var info=vr;
  var look=vorbis_look_residue0();
  var ci=vd.vi.codec_setup;

  var j,k,acc=0;
  var dim;
  var maxstage=0;
  var stages,val,mult,deco;

  look.info=info;

  look.parts=info.partitions;
  look.fullbooks=ci.fullbooks;
  look.phrasebook=ci.fullbooks[info.groupbook];
  dim=look.phrasebook.dim;

  look.partbooks=calloc(look.parts,[]);

  for(j=0;j<look.parts;j++){
    stages=ilog(info.secondstages[j]);
    if(stages){
      if(stages>maxstage)maxstage=stages;
      look.partbooks[j]=calloc(stages,codebook);
      for(k=0;k<stages;k++)
        if(info.secondstages[j]&(1<<k)){
          look.partbooks[j][k]=ci.fullbooks[info.booklist[acc++]];
        }
    }
  }

  look.partvals=1;
  for(j=0;j<dim;j++)
    look.partvals*=look.parts;

  look.stages=maxstage;
  look.decodemap=calloc(look.partvals,[]);
  for(j=0;j<look.partvals;j++){
    val=j;
    mult=int(look.partvals/look.parts);
    look.decodemap[j]=calloc(dim,int16);
    for(k=0;k<dim;k++){
      deco=int(val/mult);
      val-=deco*mult;
      mult=int(mult/look.parts);
      look.decodemap[j][k]=deco;
    }
  }
  return(look);
}

/* break an abstraction and copy some code for performance purposes */
function local_book_besterror(book, a) {
  NOT_IMPLEMENTED();
}

function _encodepart(opb, vec, n, book, acc) {
  NOT_IMPLEMENTED();
}

function _01class(vb, vl, _in, ch) {
  NOT_IMPLEMENTED();
}

/* designed for stereo or other modes where the partition size is an
   integer multiple of the number of channels encoded in the current
   submap */
function _2class(vb, vl, _in, ch) {
  NOT_IMPLEMENTED();
}

function _01forward(opb, vb, vl, _in, ch, partword, encode, submap) {
  NOT_IMPLEMENTED();
}

/* a truncated packet here just means 'stop working'; it's not an error */
function _01inverse(vb, vl, _in, ch, decodepart) {
  var i,j,k,l,s;
  var look=vl;
  var info=look.info;

  /* move all this setup out later */
  var samples_per_partition=info.grouping;
  var partitions_per_word=look.phrasebook.dim;
  var max=vb.pcmend>>1;
  var end=(info.end<max?info.end:max);
  var n=end-info.begin;
  var partvals,partwords,partword,temp,offset,stagebook;

  err_out:while(1){
    if(n>0){
      partvals=int(n/samples_per_partition);
      partwords=int((partvals+partitions_per_word-1)/partitions_per_word);
      partword=calloc(ch,[]);

      for(j=0;j<ch;j++)
        partword[j]=_vorbis_block_alloc(vb,partwords,[]);

      for(s=0;s<look.stages;s++){

        /* each loop decodes on partition codeword containing
           partitions_per_word partitions */
        for(i=0,l=0;i<partvals;l++){
          if(s===0){
            /* fetch the partition word for each channel */
            for(j=0;j<ch;j++){
              temp=vorbis_book_decode(look.phrasebook,vb.opb);

              if(temp===-1 || temp>=info.partvals)break err_out; // eopbreak;
              partword[j][l]=look.decodemap[temp];
              if(partword[j][l]===NULL)break err_out; // errout;
            }
          }

          /* now we decode residual values for the partitions */
          for(k=0;k<partitions_per_word && i<partvals;k++,i++)
            for(j=0;j<ch;j++){
              offset=info.begin+i*samples_per_partition;
              if(info.secondstages[partword[j][l][k]]&(1<<s)){
                stagebook=look.partbooks[partword[j][l][k]][s];
                if(stagebook){
                  if(decodepart(stagebook,pointer(_in[j],offset),vb.opb,
                                samples_per_partition)===-1)break; // eopbreak;
                }
              }
            }
        }
      }
    }
    break;
  }

  // errout:
  // eopbreak:
  return(0);
}

function res0_inverse(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

function res1_forward(opb, vb, vl, _in, nonzero, ch, partword, submap) {
  NOT_IMPLEMENTED();
}

function res1_class(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

function res1_inverse(vb, vl, _in, nonzero, ch) {
  var i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      _in[used++]=_in[i];
  if(used)
    return(_01inverse(vb,vl,_in,used,vorbis_book_decodev_add));
  else
    return(0);
}

function res2_class(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

/* res2 is slightly more different; all the channels are interleaved
   into a single vector and encoded. */
function res2_forward(opb, vb, vl, _in, nonzero, ch, partword, submap) {
  NOT_IMPLEMENTED();
}

/* duplicate code here as speed is somewhat more important */
function res2_inverse(vb, vl, _in, nonzero, ch) {
  NOT_IMPLEMENTED();
}

var residue0_exportbundle = vorbis_func_residue();
set_kv(residue0_exportbundle, {
  pack     : null,
  unpack   : res0_unpack,
  look     : res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass    : null,
  forward  : null,
  inverse  : res0_inverse
});

var residue1_exportbundle = vorbis_func_residue();
set_kv(residue1_exportbundle, {
  pack: res0_pack,
  unpack: res0_unpack,
  look: res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass: res1_class,
  forward: res1_forward,
  inverse: res1_inverse
});

var residue2_exportbundle = vorbis_func_residue();
set_kv(residue2_exportbundle, {
  pack     : res0_pack,
  unpack   : res0_unpack,
  look     : res0_look,
  free_info: res0_free_info,
  free_look: res0_free_look,
  klass    : res2_class,
  forward  : res2_forward,
  inverse  : res2_inverse
});

/* moved from:registry.js (latedef) */
var _residue_P = [
  residue0_exportbundle,
  residue1_exportbundle,
  residue2_exportbundle
];
<|endoftext|>


<commit_before>import get from 'lodash-es/get';
import set from 'lodash-es/set';

export default class Rule {
  constructor() {
    this._validator = null;
    this._field = null;
    this._required = false;
    this._cast = false;
    this._default = null;
    this._check = null;
  }

  validator(value = null) {
    if (value === null) {
      return this._validator;
    }

    this._validator = value;
    return this;
  }

  field(value = null) {
    if (value === null) {
      return this._field;
    }

    this._field = value;
    return this;
  }

  default (value = null) {
    if (value === null) {
      return this._default;
    }

    this._default = value;
    return this;
  }

  cast() {
    this._cast = true;
    return this;
  }

  required() {
    this._required = true;
    return this;
  }

  array() {
    this._check = this._validator.array();
    return this._check;
  }

  custom() {
    this._check = this._validator.custom();
    return this._check;
  }

  date() {
    this._check = this._validator.date();
    return this._check;
  }

  email() {
    this._check = this._validator.email();
    return this._check;
  }

  enum() {
    this._check = this._validator.enum();
    return this._check;
  }

  float() {
    this._check = this._validator.float();
    return this._check;
  }

  integer() {
    this._check = this._validator.integer();
    return this._check;
  }

  regexp() {
    this._check = this._validator.regexp();
    return this._check;
  }

  string() {
    this._check = this._validator.string();
    return this._check;
  }

  check(object, errors, options) {
    const value = this._field === '*' ?
      object : get(object, this._field);

    if (this._empty(value) === true) {
      if (this._required === true) {
        errors[this._field] = {
          required: true
        };
      } else if (this._default !== null) {
        set(object, this._field, this._default);
      }

      return;
    }

    const result = this._check
      .check(this._field, value, errors, options);

    if (result !== false && this._cast === true) {
      set(object, this._field, result);
    }
  }

  _empty(value) {
    return typeof value === 'undefined' ||
      value === null ||
      value === '';
  }
}
<commit_msg>Make default nullable<commit_after>import get from 'lodash-es/get';
import set from 'lodash-es/set';

export default class Rule {
  constructor() {
    this._validator = null;
    this._field = null;
    this._required = false;
    this._cast = false;
    this._default = null;
    this._check = null;
  }

  validator(value = null) {
    if (value === null) {
      return this._validator;
    }

    this._validator = value;
    return this;
  }

  field(value = null) {
    if (value === null) {
      return this._field;
    }

    this._field = value;
    return this;
  }

  default (value = null) {
    if (value === null) {
      return this._default;
    }

    this._default = value;
    return this;
  }

  cast() {
    this._cast = true;
    return this;
  }

  required() {
    this._required = true;
    return this;
  }

  array() {
    this._check = this._validator.array();
    return this._check;
  }

  custom() {
    this._check = this._validator.custom();
    return this._check;
  }

  date() {
    this._check = this._validator.date();
    return this._check;
  }

  email() {
    this._check = this._validator.email();
    return this._check;
  }

  enum() {
    this._check = this._validator.enum();
    return this._check;
  }

  float() {
    this._check = this._validator.float();
    return this._check;
  }

  integer() {
    this._check = this._validator.integer();
    return this._check;
  }

  regexp() {
    this._check = this._validator.regexp();
    return this._check;
  }

  string() {
    this._check = this._validator.string();
    return this._check;
  }

  check(object, errors, options) {
    const value = this._field === '*' ?
      object : get(object, this._field);

    if (this._empty(value) === true) {
      if (this._required === true) {
        errors[this._field] = {
          required: true
        };
      } else if (this._default !== null) {
        set(object, this._field,
          this._default === '\\N' ? null : this._default);
      }

      return;
    }

    const result = this._check
      .check(this._field, value, errors, options);

    if (result !== false && this._cast === true) {
      set(object, this._field, result);
    }
  }

  _empty(value) {
    return typeof value === 'undefined' ||
      value === null ||
      value === '';
  }
}
<|endoftext|>


<commit_before>let fs = require('fs')

/**
 * 返回的目标数组
 * @type {Array}
 */
let files = []

module.exports = function find(path, name, file) {
  /**
   * 忽略的文件夹
   * node_modules
   * .git
   */
  if(['.git','.idea','dist','test'].indexOf(file)=='-1'){
    /**
     * 找到目标文件
     */
    if (fs.statSync(path).isFile()&&file==name) {
      return files.push(path)
    }
    /**
     * 是文件夹的话递归查找
     */
    fs.statSync(path).isDirectory()&&
    fs.readdirSync(path).forEach((file) => {
      find(path + '/' + file, name, file)
    })
    return files
  }
}<commit_msg>add sprite config scan ignore dir<commit_after>let fs = require('fs')

/**
 * 返回的目标数组
 * @type {Array}
 */
let files = []

module.exports = function find(path, name, file) {
  /**
   * 忽略的文件夹
   * node_modules
   * .git
   */
  if(['.git','.idea','dist','test', 'node_modules'].indexOf(file)=='-1'){
    /**
     * 找到目标文件
     */
    if (fs.statSync(path).isFile()&&file==name) {
      return files.push(path)
    }
    /**
     * 是文件夹的话递归查找
     */
    fs.statSync(path).isDirectory()&&
    fs.readdirSync(path).forEach((file) => {
      find(path + '/' + file, name, file)
    })
    return files
  }
}<|endoftext|>


<commit_before>
/**
 *
 * sclang - boots a supercollider language interpreter process
 *  and enables stdin/out and system level event responders
 *
 *  SuperCollider comes with an executable called sclang
 *  which can be communicated with via stdin/stdout
 *  or via OSC.
 *
 * methods:
 *   boot  - boot an sclang process
 *   write - write to stdin of the sclang process
 *   quit
 *
 */

var
  _ = require('underscore'),
  EventEmitter = require('events').EventEmitter,
  spawn = require('child_process').spawn,
  path = require('path'),
  Logger = require('./logger'),
  Q = require('q'),
  uuid = require('node-uuid'),
  join = require('path').join,
  yaml = require('js-yaml'),
  temp = require('temp'),
  fs   = require('fs'),
  untildify = require('untildify');

import {SclangIO, STATES} from './sclang-io';

class SCLang extends EventEmitter {

  /*
   * @param {object} options - sclang command line options
   */
  constructor(options) {
    super();
    this.options = options || {};
    this.process = null;
    this.log = new Logger(this.options.debug, this.options.echo);
    this.log.dbug(this.options);
  }

  /**
   * build args for sclang
   *
   *   -d <path>                      Set runtime directory
   *   -D                             Enter daemon mode (no input)
   *   -g <memory-growth>[km]         Set heap growth (default 256k)
   *   -h                             Display this message and exit
   *   -l <path>                      Set library configuration file
   *   -m <memory-space>[km]          Set initial heap size (default 2m)
   *   -r                             Call Main.run on startup
   *   -s                             Call Main.stop on shutdown
   *   -u <network-port-number>       Set UDP listening port (default 57120)
   *   -i <ide-name>                  Specify IDE name (for enabling IDE-specific class code, default "none")
   *   -a                             Standalone mode
   */
  args(options) {
    var o = [];
    if (options.executeFile) {
      o.push(options.executeFile);
    }
    o.push('-u', options.langPort);
    if (options.config) {
      o.push('-l', options.config);
    }
    return o;
  }

  /**
   * makeSclangConfig
   *
   * make sclang_config.yaml as a temporary file
   * with the supplied values
   *
   * This is the config file that sclang reads, specifying
   * includePaths and excludePaths
   *
   * @param {object} options - options to write to file
   * @returns {Promise} resolving with the path of the temp config file
   */
  makeSclangConfig(config) {
    /**
      write options as yaml to a temp file
      and return the path
    **/
    var addPath, includePaths, str;
    var deferred = Q.defer();

    str = yaml.safeDump(config, {indent: 4});
    temp.open('sclang-config', function(err, info) {
      if(err) {
        return deferred.reject(err);
      }
      fs.write(info.fd, str);
      fs.close(info.fd, function(err) {
        if(err) {
          return deferred.reject(err);
        }
        deferred.resolve(info.path);
      });
    });

    return deferred.promise;
  }

  /**
   * boot
   *
   * start sclang as a subprocess
   *
   * @returns {Promise}
   */
  boot() {
    this.setState(STATES.BOOTING);

    // merge supercollider.js options with any sclang_conf
    var config = this.sclangConfigOptions(this.options);

    if(config.includePaths || config.excludePaths) {
      return this.makeSclangConfig(config)
        .then((configPath) => {
          return this.spawnProcess(this.options.sclang, _.extend({}, this.options, {config: configPath}));
        });
    } else {
      return this.spawnProcess(this.options.sclang, _.extend({}, this.options));
    }
  }

  /**
   * spawnProcess - starts the sclang executable
   *
   * sets this.process
   * adds state listeners
   *
   * @param {string} execPath - path to sclang
   * @param {object} commandLineOptions - options for the command line
   *                filtered with this.args so it will only include values
   *                that sclang uses.
   * @returns {Promise}
   *     resolves null on successful boot and compile
   *     rejects on failure to boot or failure to compile the class library
   */
  spawnProcess(execPath, commandLineOptions) {
    var deferred = Q.defer();

    this.process = spawn(execPath, this.args(commandLineOptions),
      {
        cwd: path.dirname(execPath)
      });

    var bootListener = (state) => {
      if (state === 'ready') {
        deferred.resolve();
        this.removeListener('state', bootListener);
      } else if (state === 'compileError') {
        deferred.reject(this.stateWatcher.compileErrors);
        this.removeListener('state', bootListener);
        // probably should remove all listeners
      }
    }

    // temporary listener until booted ready or compileError
    // that removes itself
    this.addListener('state', bootListener);

    // long term listeners
    this.installListeners();

    return deferred.promise;
  }

  /**
   * sclangConfigOptions
   *
   * Builds the options that will be written to the config file that is read by sclang
   * If supercolliderjs-conf specifies a sclang_conf path
   * then this is read and any includePaths and excludePaths are merged
   *
   * throws error if config cannot be read
   *
   * @param {object} options - supercolliderJs options
   * @returns {object} - sclang_config variables
   */
  sclangConfigOptions(options) {
    var
      runtimeIncludePaths,
      sclang_conf = {},
      config = {};

    // add sc-classes to sclang's compile paths
    if(options.errorsAsJSON) {
      runtimeIncludePaths = [path.resolve(__dirname, '../sc-classes')];
    }

    if(options.sclang_conf) {
      try {
        sclang_conf = yaml.safeLoad(fs.readFileSync(untildify(options.sclang_conf), 'utf8'));
      } catch (e) {
        this.log.err(e);
        throw 'Cannot open or read specified sclang_conf ' + options.sclang_conf;
      }
    }

    return {
      includePaths: _.union(sclang_conf.includePaths, options.includePaths, runtimeIncludePaths),
      excludePaths: _.union(sclang_conf.excludePaths, options.excludePaths),
      postInlineWarning: _.isUndefined(options.postInlineWarnings) ? sclang_conf.postInlineWarnings : options.postInlineWarnings
    };
  }

  /**
    * listen to process and SclangIO events
    */
  installListeners() {
    this.stateWatcher = new SclangIO(this);

    if (this.options.stdin) {
      // stdin of the global top level nodejs process
      process.stdin.setEncoding('utf8');
      process.stdin.on('data', (chunk) => {
        if (chunk) {
          this.write(chunk, null, true);
        }
      });
    }
    this.process.stdout.on('data', (data) => {
      this.stateWatcher.parse(String(data));
    });
    this.process.stderr.on('data', (data) => {
      var error = String(data);
      this.log.stderr(error);
      this.emit('stderr', error);
    });
    this.process.on('error', (err) => {
      this.log.err('ERROR:' + err, 'error');
      this.emit('stderr', err);
    });
    this.process.on('close', (code, signal) => {
      this.log.dbug('close ' + code + signal);
      this.emit('exit', code);
      this.setState(null);
    });
    this.process.on('exit', (code, signal) => {
      this.log.dbug('exit ' + code + signal);
      this.emit('exit', code);
      this.setState(null);
    });
    this.process.on('disconnect', () => {
      this.log.dbug('disconnect');
      this.emit('exit');
      this.setState(null);
    });

    var echo = (...args) => this.emit(...args);
    this.stateWatcher.on('interpreterLoaded', echo);
    this.stateWatcher.on('error', echo);
    this.stateWatcher.on('stdout', echo);
    this.stateWatcher.on('state', echo);
  }

  /**
   * write
   *
   * send a raw string to sclang to be interpreted
   * callback is called after write is complete
   */
  write(chunk, callback, noEcho) {
    if (!noEcho) {
      this.log.stdin(chunk);
    }
    this.process.stdin.write(chunk, 'UTF-8');
    // escape character means execute the currently accumulated command line as SC code
    this.process.stdin.write('\x0c', null, callback);
  }

  /**
    * initInterpreter
    *
    * make sclang execute the interpret.scd file
    * to load the functions used by interpret
    */
  initInterpreter() {
    var scriptPath = join(__dirname, '../sc/interpret.scd'),
        deferred = Q.defer();

    // after the interpreter finishes processing the script this will be triggered
    this.once('interpreterLoaded', () => {
      // store the original configuration path into Library.at('supercolliderjs', 'sclang_conf')
      // so that it can be accessed by Quarks
      if (this.options.sclang_conf) {
        var configPath = path.resolve(untildify(this.options.sclang_conf));
        var setConfigPath = 'Library.put(\'supercolliderjs\', \'sclang_conf\', "' + configPath + '");';
        this.interpret(setConfigPath, null, true, false, false)
          .then(() => { deferred.resolve(this); },
            deferred.reject);
      }
    });

    // load the json interpreter bridge
    this.write('thisProcess.interpreter.executeFile("' + scriptPath + '");\n', null, true);
    return deferred.promise;
  }

  /**
   * interpret
   *
   * evaluates code in sclang
   * and returns a promise
   *
   * resolves promise with result or rejects with error as JSON
   *
   * @param {String} code
   *        source code to evaluate
   * @param {String} nowExecutingPath
            set thisProcess.nowExecutingPath
   *        for use in a REPL to evaluate text in a file
   *        and let sclang know what file it is executing.
   * @param {Boolean} asString
   *        return result .asString for post window
   *        otherwise returns result as a JSON object
   * @param {Boolean} postErrors
   *        call error.reportError on any errors
   *        which posts call stack, receiver, args, etc
   * @param {Boolean} getBacktrace
   *        return full backtrace
   * @returns {Promise}
   */
  interpret(code, nowExecutingPath, asString, postErrors, getBacktrace) {
    var deferred = Q.defer(),
        escaped = code.replace(/[\n\r]/g, '__NL__').replace(/\\/g, '__SLASH__').replace(/\"/g, '\\"'),
        scstring = '"' + escaped + '"',
        guid = uuid.v1(),
        guidString = '"' + guid + '"',
        nep = nowExecutingPath ? '"' + nowExecutingPath + '"' : 'nil',
        rras = asString ? 'true' : 'false',
        pe = postErrors ? 'true' : 'false',
        bt = getBacktrace ? 'true' : 'false',
        args = [guidString, scstring, nep, rras, pe, bt].join(','),
        scode;

    scode = 'Library.at(\\supercolliderjs, \\interpret).value(' + args + ');"SUPERCOLLIDERJS.interpreted".postln;\n';

    this.stateWatcher.registerCall(guid, deferred);
    this.write(scode, null, true);
    return deferred.promise;
  }

  /**
   * @private
   */
  setState(state) {
    this.stateWatcher.setState(state);
  }

  quit() {
    var deferred = Q.defer();
    if (this.process) {
      this.process.once('exit', () => {
        this.process = null;
        this.setState(null);
        deferred.resolve();
      });
      // request a polite shutdown
      this.process.kill('SIGINT');
      setTimeout(() => {
        // 3.6.6 doesn't fully respond to SIGINT
        // but SIGTERM causes it to crash
        if(this.process) {
          this.process.kill('SIGTERM');
        }
      }, 250);
    } else {
      this.setState(null);
      deferred.resolve();
    }
    return deferred.promise;
  }
}

/**
  * alternate constructor
  * resolves options, boots and loads interpreter
  *
  * remember to add a .fail handler to the returned
  * Promise so that you catch any propagated errors
  *
  * @param {object} sclang options
  * @returns: {Promise}
  */
SCLang.boot = function(options) {
  var resolveOptions = require('./resolveOptions');

  return resolveOptions(options.config, options).then(function(options) {

    var sclang = new SCLang(options);

    return sclang.boot()
      .then(function() {
        return sclang.initInterpreter();
      });
  });

};

module.exports = SCLang;
<commit_msg>jslint<commit_after>
/**
 *
 * sclang - boots a supercollider language interpreter process
 *  and enables stdin/out and system level event responders
 *
 *  SuperCollider comes with an executable called sclang
 *  which can be communicated with via stdin/stdout
 *  or via OSC.
 *
 * methods:
 *   boot  - boot an sclang process
 *   write - write to stdin of the sclang process
 *   quit
 *
 */

var
  _ = require('underscore'),
  EventEmitter = require('events').EventEmitter,
  spawn = require('child_process').spawn,
  path = require('path'),
  Logger = require('./logger'),
  Q = require('q'),
  uuid = require('node-uuid'),
  join = require('path').join,
  yaml = require('js-yaml'),
  temp = require('temp'),
  fs   = require('fs'),
  untildify = require('untildify');

import {SclangIO, STATES} from './sclang-io';

class SCLang extends EventEmitter {

  /*
   * @param {object} options - sclang command line options
   */
  constructor(options) {
    super();
    this.options = options || {};
    this.process = null;
    this.log = new Logger(this.options.debug, this.options.echo);
    this.log.dbug(this.options);
  }

  /**
   * build args for sclang
   *
   *   -d <path>                      Set runtime directory
   *   -D                             Enter daemon mode (no input)
   *   -g <memory-growth>[km]         Set heap growth (default 256k)
   *   -h                             Display this message and exit
   *   -l <path>                      Set library configuration file
   *   -m <memory-space>[km]          Set initial heap size (default 2m)
   *   -r                             Call Main.run on startup
   *   -s                             Call Main.stop on shutdown
   *   -u <network-port-number>       Set UDP listening port (default 57120)
   *   -i <ide-name>                  Specify IDE name (for enabling IDE-specific class code, default "none")
   *   -a                             Standalone mode
   */
  args(options) {
    var o = [];
    if (options.executeFile) {
      o.push(options.executeFile);
    }
    o.push('-u', options.langPort);
    if (options.config) {
      o.push('-l', options.config);
    }
    return o;
  }

  /**
   * makeSclangConfig
   *
   * make sclang_config.yaml as a temporary file
   * with the supplied values
   *
   * This is the config file that sclang reads, specifying
   * includePaths and excludePaths
   *
   * @param {object} options - options to write to file
   * @returns {Promise} resolving with the path of the temp config file
   */
  makeSclangConfig(config) {
    /**
      write options as yaml to a temp file
      and return the path
    **/
    var addPath, includePaths, str;
    var deferred = Q.defer();

    str = yaml.safeDump(config, {indent: 4});
    temp.open('sclang-config', function(err, info) {
      if(err) {
        return deferred.reject(err);
      }
      fs.write(info.fd, str);
      fs.close(info.fd, function(err) {
        if(err) {
          return deferred.reject(err);
        }
        deferred.resolve(info.path);
      });
    });

    return deferred.promise;
  }

  /**
   * boot
   *
   * start sclang as a subprocess
   *
   * @returns {Promise}
   */
  boot() {
    this.setState(STATES.BOOTING);

    // merge supercollider.js options with any sclang_conf
    var config = this.sclangConfigOptions(this.options);

    if(config.includePaths || config.excludePaths) {
      return this.makeSclangConfig(config)
        .then((configPath) => {
          return this.spawnProcess(this.options.sclang, _.extend({}, this.options, {config: configPath}));
        });
    } else {
      return this.spawnProcess(this.options.sclang, _.extend({}, this.options));
    }
  }

  /**
   * spawnProcess - starts the sclang executable
   *
   * sets this.process
   * adds state listeners
   *
   * @param {string} execPath - path to sclang
   * @param {object} commandLineOptions - options for the command line
   *                filtered with this.args so it will only include values
   *                that sclang uses.
   * @returns {Promise}
   *     resolves null on successful boot and compile
   *     rejects on failure to boot or failure to compile the class library
   */
  spawnProcess(execPath, commandLineOptions) {
    var deferred = Q.defer();

    this.process = spawn(execPath, this.args(commandLineOptions),
      {
        cwd: path.dirname(execPath)
      });

    var bootListener = (state) => {
      if (state === 'ready') {
        deferred.resolve();
        this.removeListener('state', bootListener);
      } else if (state === 'compileError') {
        deferred.reject(this.stateWatcher.compileErrors);
        this.removeListener('state', bootListener);
        // probably should remove all listeners
      }
    };

    // temporary listener until booted ready or compileError
    // that removes itself
    this.addListener('state', bootListener);

    // long term listeners
    this.installListeners();

    return deferred.promise;
  }

  /**
   * sclangConfigOptions
   *
   * Builds the options that will be written to the config file that is read by sclang
   * If supercolliderjs-conf specifies a sclang_conf path
   * then this is read and any includePaths and excludePaths are merged
   *
   * throws error if config cannot be read
   *
   * @param {object} options - supercolliderJs options
   * @returns {object} - sclang_config variables
   */
  sclangConfigOptions(options) {
    var
      runtimeIncludePaths,
      sclang_conf = {},
      config = {};

    // add sc-classes to sclang's compile paths
    if(options.errorsAsJSON) {
      runtimeIncludePaths = [path.resolve(__dirname, '../sc-classes')];
    }

    if(options.sclang_conf) {
      try {
        sclang_conf = yaml.safeLoad(fs.readFileSync(untildify(options.sclang_conf), 'utf8'));
      } catch (e) {
        this.log.err(e);
        throw 'Cannot open or read specified sclang_conf ' + options.sclang_conf;
      }
    }

    return {
      includePaths: _.union(sclang_conf.includePaths, options.includePaths, runtimeIncludePaths),
      excludePaths: _.union(sclang_conf.excludePaths, options.excludePaths),
      postInlineWarning: _.isUndefined(options.postInlineWarnings) ? sclang_conf.postInlineWarnings : options.postInlineWarnings
    };
  }

  /**
    * listen to process and SclangIO events
    */
  installListeners() {
    this.stateWatcher = new SclangIO(this);

    if (this.options.stdin) {
      // stdin of the global top level nodejs process
      process.stdin.setEncoding('utf8');
      process.stdin.on('data', (chunk) => {
        if (chunk) {
          this.write(chunk, null, true);
        }
      });
    }
    this.process.stdout.on('data', (data) => {
      this.stateWatcher.parse(String(data));
    });
    this.process.stderr.on('data', (data) => {
      var error = String(data);
      this.log.stderr(error);
      this.emit('stderr', error);
    });
    this.process.on('error', (err) => {
      this.log.err('ERROR:' + err, 'error');
      this.emit('stderr', err);
    });
    this.process.on('close', (code, signal) => {
      this.log.dbug('close ' + code + signal);
      this.emit('exit', code);
      this.setState(null);
    });
    this.process.on('exit', (code, signal) => {
      this.log.dbug('exit ' + code + signal);
      this.emit('exit', code);
      this.setState(null);
    });
    this.process.on('disconnect', () => {
      this.log.dbug('disconnect');
      this.emit('exit');
      this.setState(null);
    });

    var echo = (...args) => this.emit(...args);
    this.stateWatcher.on('interpreterLoaded', echo);
    this.stateWatcher.on('error', echo);
    this.stateWatcher.on('stdout', echo);
    this.stateWatcher.on('state', echo);
  }

  /**
   * write
   *
   * send a raw string to sclang to be interpreted
   * callback is called after write is complete
   */
  write(chunk, callback, noEcho) {
    if (!noEcho) {
      this.log.stdin(chunk);
    }
    this.process.stdin.write(chunk, 'UTF-8');
    // escape character means execute the currently accumulated command line as SC code
    this.process.stdin.write('\x0c', null, callback);
  }

  /**
    * initInterpreter
    *
    * make sclang execute the interpret.scd file
    * to load the functions used by interpret
    */
  initInterpreter() {
    var scriptPath = join(__dirname, '../sc/interpret.scd'),
        deferred = Q.defer();

    // after the interpreter finishes processing the script this will be triggered
    this.once('interpreterLoaded', () => {
      // store the original configuration path into Library.at('supercolliderjs', 'sclang_conf')
      // so that it can be accessed by Quarks
      if (this.options.sclang_conf) {
        var configPath = path.resolve(untildify(this.options.sclang_conf));
        var setConfigPath = 'Library.put(\'supercolliderjs\', \'sclang_conf\', "' + configPath + '");';
        this.interpret(setConfigPath, null, true, false, false)
          .then(() => { deferred.resolve(this); },
            deferred.reject);
      }
    });

    // load the json interpreter bridge
    this.write('thisProcess.interpreter.executeFile("' + scriptPath + '");\n', null, true);
    return deferred.promise;
  }

  /**
   * interpret
   *
   * evaluates code in sclang
   * and returns a promise
   *
   * resolves promise with result or rejects with error as JSON
   *
   * @param {String} code
   *        source code to evaluate
   * @param {String} nowExecutingPath
            set thisProcess.nowExecutingPath
   *        for use in a REPL to evaluate text in a file
   *        and let sclang know what file it is executing.
   * @param {Boolean} asString
   *        return result .asString for post window
   *        otherwise returns result as a JSON object
   * @param {Boolean} postErrors
   *        call error.reportError on any errors
   *        which posts call stack, receiver, args, etc
   * @param {Boolean} getBacktrace
   *        return full backtrace
   * @returns {Promise}
   */
  interpret(code, nowExecutingPath, asString, postErrors, getBacktrace) {
    var deferred = Q.defer(),
        escaped = code.replace(/[\n\r]/g, '__NL__').replace(/\\/g, '__SLASH__').replace(/\"/g, '\\"'),
        scstring = '"' + escaped + '"',
        guid = uuid.v1(),
        guidString = '"' + guid + '"',
        nep = nowExecutingPath ? '"' + nowExecutingPath + '"' : 'nil',
        rras = asString ? 'true' : 'false',
        pe = postErrors ? 'true' : 'false',
        bt = getBacktrace ? 'true' : 'false',
        args = [guidString, scstring, nep, rras, pe, bt].join(','),
        scode;

    scode = 'Library.at(\\supercolliderjs, \\interpret).value(' + args + ');"SUPERCOLLIDERJS.interpreted".postln;\n';

    this.stateWatcher.registerCall(guid, deferred);
    this.write(scode, null, true);
    return deferred.promise;
  }

  /**
   * @private
   */
  setState(state) {
    this.stateWatcher.setState(state);
  }

  quit() {
    var deferred = Q.defer();
    if (this.process) {
      this.process.once('exit', () => {
        this.process = null;
        this.setState(null);
        deferred.resolve();
      });
      // request a polite shutdown
      this.process.kill('SIGINT');
      setTimeout(() => {
        // 3.6.6 doesn't fully respond to SIGINT
        // but SIGTERM causes it to crash
        if(this.process) {
          this.process.kill('SIGTERM');
        }
      }, 250);
    } else {
      this.setState(null);
      deferred.resolve();
    }
    return deferred.promise;
  }
}

/**
  * alternate constructor
  * resolves options, boots and loads interpreter
  *
  * remember to add a .fail handler to the returned
  * Promise so that you catch any propagated errors
  *
  * @param {object} sclang options
  * @returns: {Promise}
  */
SCLang.boot = function(options) {
  var resolveOptions = require('./resolveOptions');

  return resolveOptions(options.config, options).then(function(options) {

    var sclang = new SCLang(options);

    return sclang.boot()
      .then(function() {
        return sclang.initInterpreter();
      });
  });

};

module.exports = SCLang;
<|endoftext|>


<commit_before><commit_msg>Fixes #13.  Pull sink.js.<commit_after><|endoftext|>


<commit_before>if (CSMath.accurate['sqrt']) {
	CSMath.sqrt = Math.sqrt
} else {
	/* Algorithm from 'Divide, Square Root and Remainder Algorithms for the IA64 Architecture */

	Math.sqrt = function (a) {
		var y0 = 1.0 / Math.sqrta(a)

		var H0 = 0.5 * y0,
			S0 = (a * y0)

		var d0 = -Math.fms(S0, H0, 0.5)

		var H1 = Math.fma(d0, H0, H0),
			S1 = Math.fma(d0, S0, S0)

		var d1 = -Math.fms(S1, H1, 0.5)

		var H2 = Math.fma(d1, H1, H1),
			S2 = Math.fma(d1, S1, S1)

		var d2 = -Math.fms(S2, H2, 0.5),
			e2 = -Math.fms(S2, S2, a)

		var H3 = Math.fma(d2, H2, H2),
			S3 = Math.fma(e2, H2, S2)

		var e3 = -Math.fms(S3, S3, a)

		return Math.fma(e3, H3, S3)
	}
}

/* TODO: The root functions have low precision */

CSMath.cbrt = function(a) {
	return Math.pow(a, 1.0 / 3.0)
}<commit_msg>Yes, I fucked up, it did overwrite Math.sqrt instead of CSMath.sqrt<commit_after>if (CSMath.accurate['sqrt']) {
	CSMath.sqrt = Math.sqrt
} else {
	/* Algorithm from 'Divide, Square Root and Remainder Algorithms for the IA64 Architecture */

	var sqrtApproximation = Math.sqrt

	CSMath.sqrt = function (a) {
		var y0 = 1.0 / sqrtApproximation(a)

		var H0 = 0.5 * y0,
			S0 = (a * y0)

		var d0 = -CSMath.fms(S0, H0, 0.5)

		var H1 = CSMath.fma(d0, H0, H0),
			S1 = CSMath.fma(d0, S0, S0)

		var d1 = -CSMath.fms(S1, H1, 0.5)

		var H2 = CSMath.fma(d1, H1, H1),
			S2 = CSMath.fma(d1, S1, S1)

		var d2 = -CSMath.fms(S2, H2, 0.5),
			e2 = -CSMath.fms(S2, S2, a)

		var H3 = CSMath.fma(d2, H2, H2),
			S3 = CSMath.fma(e2, H2, S2)

		var e3 = -CSMath.fms(S3, S3, a)

		return CSMath.fma(e3, H3, S3)
	}
}

/* TODO: The root functions have low precision */

CSMath.cbrt = function(a) {
	return Math.pow(a, 1.0 / 3.0)
}<|endoftext|>


<commit_before>/*global angular */
(function (ng) {
    'use strict';

    function throwNoKeyException() {
        throw new Error('You need to set the "key" attribute to your public reCaptcha key. If you don\'t have a key, please get one from https://www.google.com/recaptcha/admin/create');
    }

    var app = ng.module('vcRecaptcha');

    /**
     * An angular service to wrap the reCaptcha API
     */
    app.provider('vcRecaptchaService', function(){
        var provider = this;
        var config = {};
        provider.onLoadFunctionName = 'vcRecaptchaApiLoaded';

        /**
         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param defaults  object which overrides the current defaults object.
         */
        provider.setDefaults = function(defaults){
            ng.copy(defaults, config);
        };

        /**
         * Sets the reCaptcha key which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param siteKey  the reCaptcha public key (refer to the README file if you don't know what this is).
         */
        provider.setSiteKey = function(siteKey){
            config.key = siteKey;
        };

        /**
         * Sets the reCaptcha theme which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param theme  The reCaptcha theme.
         */
        provider.setTheme = function(theme){
            config.theme = theme;
        };

        /**
         * Sets the reCaptcha stoken which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param stoken  The reCaptcha stoken.
         */
        provider.setStoken = function(stoken){
            config.stoken = stoken;
        };

        /**
         * Sets the reCaptcha size which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param size  The reCaptcha size.
         */
        provider.setSize = function(size){
            config.size = size;
        };

        /**
         * Sets the reCaptcha type which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param type  The reCaptcha type.
         */
        provider.setType = function(type){
            config.type = type;
        };

        /**
         * Sets the reCaptcha language which will be used by default is not specified in a specific directive instance.
         *
         * @param lang  The reCaptcha language.
         */
        provider.setLang = function(lang){
            config.lang = lang;
        };

        /**
         * Sets the reCaptcha badge position which will be used by default if not specified in a specific directive instance.
         *
         * @param badge  The reCaptcha badge position.
         */
        provider.setBadge = function(badge){
            config.badge = badge;
        };

        /**
         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param onLoadFunctionName  string name which overrides the name of the onload function. Should match what is in the recaptcha script querystring onload value.
         */
        provider.setOnLoadFunctionName = function(onLoadFunctionName){
            provider.onLoadFunctionName = onLoadFunctionName;
        };

        provider.$get = ['$rootScope','$window', '$q', '$document', '$interval', function ($rootScope, $window, $q, $document, $interval) {
            var deferred = $q.defer(), promise = deferred.promise, instances = {}, recaptcha;

            $window.vcRecaptchaApiLoadedCallback = $window.vcRecaptchaApiLoadedCallback || [];

            var callback = function () {
                recaptcha = $window.grecaptcha;

                deferred.resolve(recaptcha);
            };

            $window.vcRecaptchaApiLoadedCallback.push(callback);

            $window[provider.onLoadFunctionName] = function () {
                $window.vcRecaptchaApiLoadedCallback.forEach(function(callback) {
                    callback();
                });
            };

            function getRecaptcha() {
                if (!!recaptcha) {
                    return $q.when(recaptcha);
                }

                return promise;
            }

            function validateRecaptchaInstance() {
                if (!recaptcha) {
                    throw new Error('reCaptcha has not been loaded yet.');
                }
            }

            // Check if grecaptcha is not defined already.
            if (ng.isDefined($window.grecaptcha)) {
                callback();
            } else if ($window.document.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) {
                // wait for script to be loaded.
                var intervalWait = $interval(function() {
                    if (ng.isDefined($window.grecaptcha)) {
                        $interval.cancel(intervalWait);
                        callback();
                    }
                }, 25);
            } else {
                // Generate link on demand
                var script = $window.document.createElement('script');
                script.async = true;
                script.defer = true;
                script.src = 'https://www.google.com/recaptcha/api.js?onload='+provider.onLoadFunctionName+'&render=explicit';
                $document.find('body')[0].appendChild(script);
            }

            return {

                /**
                 * Creates a new reCaptcha object
                 *
                 * @param elm  the DOM element where to put the captcha
                 * @param conf the captcha object configuration
                 * @throws NoKeyException    if no key is provided in the provider config or the directive instance (via attribute)
                 */
                create: function (elm, conf) {

                    conf.sitekey = conf.key || config.key;
                    conf.theme = conf.theme || config.theme;
                    conf.stoken = conf.stoken || config.stoken;
                    conf.size = conf.size || config.size;
                    conf.type = conf.type || config.type;
                    conf.hl = conf.lang || config.lang;
                    conf.badge = conf.badge || config.badge;

                    if (!conf.sitekey || conf.sitekey.length !== 40) {
                        throwNoKeyException();
                    }
                    return getRecaptcha().then(function (recaptcha) {
                        var widgetId = recaptcha.render(elm, conf);
                        instances[widgetId] = elm;
                        return widgetId;
                    });
                },

                /**
                 * Reloads the reCaptcha
                 */
                reload: function (widgetId) {
                    validateRecaptchaInstance();

                    recaptcha.reset(widgetId);

                    // Let everyone know this widget has been reset.
                    $rootScope.$broadcast('reCaptchaReset', widgetId);
                },

                /**
                 * Executes the reCaptcha
                 */
                execute: function (widgetId) {
                    validateRecaptchaInstance();

                    recaptcha.execute(widgetId);
                },

                /**
                 * Get/Set reCaptcha language
                 */
                useLang: function (widgetId, lang) {
                    var instance = instances[widgetId];

                    if (instance) {
                        var iframe = instance.querySelector('iframe');
                        if (lang) {
                            // Setter
                            if (iframe && iframe.src) {
                                var s = iframe.src;
                                if (/[?&]hl=/.test(s)) {
                                    s = s.replace(/([?&]hl=)\w+/, '$1' + lang);
                                } else {
                                    s += ((s.indexOf('?') === -1) ? '?' : '&') + 'hl=' + lang;
                                }

                                iframe.src = s;
                            }
                        } else {
                            // Getter
                            if (iframe && iframe.src && /[?&]hl=\w+/.test(iframe.src)) {
                                return iframe.src.replace(/.+[?&]hl=(\w+)([^\w].+)?/, '$1');
                            } else {
                                return null;
                            }
                        }
                    } else {
                        throw new Error('reCaptcha Widget ID not exists', widgetId);
                    }
                },

                /**
                 * Gets the response from the reCaptcha widget.
                 *
                 * @see https://developers.google.com/recaptcha/docs/display#js_api
                 *
                 * @returns {String}
                 */
                getResponse: function (widgetId) {
                    validateRecaptchaInstance();

                    return recaptcha.getResponse(widgetId);
                },

                /**
                 * Gets reCaptcha instance and configuration
                 */
                getInstance: function (widgetId) {
                    return instances[widgetId];
                },

                /**
                 * Destroy reCaptcha instance.
                 */
                destroy: function (widgetId) {
                    delete instances[widgetId];
                }
            };

        }];
    });

}(angular));
<commit_msg>Remove site key length check<commit_after>/*global angular */
(function (ng) {
    'use strict';

    function throwNoKeyException() {
        throw new Error('You need to set the "key" attribute to your public reCaptcha key. If you don\'t have a key, please get one from https://www.google.com/recaptcha/admin/create');
    }

    var app = ng.module('vcRecaptcha');

    /**
     * An angular service to wrap the reCaptcha API
     */
    app.provider('vcRecaptchaService', function(){
        var provider = this;
        var config = {};
        provider.onLoadFunctionName = 'vcRecaptchaApiLoaded';

        /**
         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param defaults  object which overrides the current defaults object.
         */
        provider.setDefaults = function(defaults){
            ng.copy(defaults, config);
        };

        /**
         * Sets the reCaptcha key which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param siteKey  the reCaptcha public key (refer to the README file if you don't know what this is).
         */
        provider.setSiteKey = function(siteKey){
            config.key = siteKey;
        };

        /**
         * Sets the reCaptcha theme which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param theme  The reCaptcha theme.
         */
        provider.setTheme = function(theme){
            config.theme = theme;
        };

        /**
         * Sets the reCaptcha stoken which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param stoken  The reCaptcha stoken.
         */
        provider.setStoken = function(stoken){
            config.stoken = stoken;
        };

        /**
         * Sets the reCaptcha size which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param size  The reCaptcha size.
         */
        provider.setSize = function(size){
            config.size = size;
        };

        /**
         * Sets the reCaptcha type which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param type  The reCaptcha type.
         */
        provider.setType = function(type){
            config.type = type;
        };

        /**
         * Sets the reCaptcha language which will be used by default is not specified in a specific directive instance.
         *
         * @param lang  The reCaptcha language.
         */
        provider.setLang = function(lang){
            config.lang = lang;
        };

        /**
         * Sets the reCaptcha badge position which will be used by default if not specified in a specific directive instance.
         *
         * @param badge  The reCaptcha badge position.
         */
        provider.setBadge = function(badge){
            config.badge = badge;
        };

        /**
         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
         *
         * @since 2.5.0
         * @param onLoadFunctionName  string name which overrides the name of the onload function. Should match what is in the recaptcha script querystring onload value.
         */
        provider.setOnLoadFunctionName = function(onLoadFunctionName){
            provider.onLoadFunctionName = onLoadFunctionName;
        };

        provider.$get = ['$rootScope','$window', '$q', '$document', '$interval', function ($rootScope, $window, $q, $document, $interval) {
            var deferred = $q.defer(), promise = deferred.promise, instances = {}, recaptcha;

            $window.vcRecaptchaApiLoadedCallback = $window.vcRecaptchaApiLoadedCallback || [];

            var callback = function () {
                recaptcha = $window.grecaptcha;

                deferred.resolve(recaptcha);
            };

            $window.vcRecaptchaApiLoadedCallback.push(callback);

            $window[provider.onLoadFunctionName] = function () {
                $window.vcRecaptchaApiLoadedCallback.forEach(function(callback) {
                    callback();
                });
            };

            function getRecaptcha() {
                if (!!recaptcha) {
                    return $q.when(recaptcha);
                }

                return promise;
            }

            function validateRecaptchaInstance() {
                if (!recaptcha) {
                    throw new Error('reCaptcha has not been loaded yet.');
                }
            }

            // Check if grecaptcha is not defined already.
            if (ng.isDefined($window.grecaptcha)) {
                callback();
            } else if ($window.document.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) {
                // wait for script to be loaded.
                var intervalWait = $interval(function() {
                    if (ng.isDefined($window.grecaptcha)) {
                        $interval.cancel(intervalWait);
                        callback();
                    }
                }, 25);
            } else {
                // Generate link on demand
                var script = $window.document.createElement('script');
                script.async = true;
                script.defer = true;
                script.src = 'https://www.google.com/recaptcha/api.js?onload='+provider.onLoadFunctionName+'&render=explicit';
                $document.find('body')[0].appendChild(script);
            }

            return {

                /**
                 * Creates a new reCaptcha object
                 *
                 * @param elm  the DOM element where to put the captcha
                 * @param conf the captcha object configuration
                 * @throws NoKeyException    if no key is provided in the provider config or the directive instance (via attribute)
                 */
                create: function (elm, conf) {

                    conf.sitekey = conf.key || config.key;
                    conf.theme = conf.theme || config.theme;
                    conf.stoken = conf.stoken || config.stoken;
                    conf.size = conf.size || config.size;
                    conf.type = conf.type || config.type;
                    conf.hl = conf.lang || config.lang;
                    conf.badge = conf.badge || config.badge;

                    if (!conf.sitekey) {
                        throwNoKeyException();
                    }
                    return getRecaptcha().then(function (recaptcha) {
                        var widgetId = recaptcha.render(elm, conf);
                        instances[widgetId] = elm;
                        return widgetId;
                    });
                },

                /**
                 * Reloads the reCaptcha
                 */
                reload: function (widgetId) {
                    validateRecaptchaInstance();

                    recaptcha.reset(widgetId);

                    // Let everyone know this widget has been reset.
                    $rootScope.$broadcast('reCaptchaReset', widgetId);
                },

                /**
                 * Executes the reCaptcha
                 */
                execute: function (widgetId) {
                    validateRecaptchaInstance();

                    recaptcha.execute(widgetId);
                },

                /**
                 * Get/Set reCaptcha language
                 */
                useLang: function (widgetId, lang) {
                    var instance = instances[widgetId];

                    if (instance) {
                        var iframe = instance.querySelector('iframe');
                        if (lang) {
                            // Setter
                            if (iframe && iframe.src) {
                                var s = iframe.src;
                                if (/[?&]hl=/.test(s)) {
                                    s = s.replace(/([?&]hl=)\w+/, '$1' + lang);
                                } else {
                                    s += ((s.indexOf('?') === -1) ? '?' : '&') + 'hl=' + lang;
                                }

                                iframe.src = s;
                            }
                        } else {
                            // Getter
                            if (iframe && iframe.src && /[?&]hl=\w+/.test(iframe.src)) {
                                return iframe.src.replace(/.+[?&]hl=(\w+)([^\w].+)?/, '$1');
                            } else {
                                return null;
                            }
                        }
                    } else {
                        throw new Error('reCaptcha Widget ID not exists', widgetId);
                    }
                },

                /**
                 * Gets the response from the reCaptcha widget.
                 *
                 * @see https://developers.google.com/recaptcha/docs/display#js_api
                 *
                 * @returns {String}
                 */
                getResponse: function (widgetId) {
                    validateRecaptchaInstance();

                    return recaptcha.getResponse(widgetId);
                },

                /**
                 * Gets reCaptcha instance and configuration
                 */
                getInstance: function (widgetId) {
                    return instances[widgetId];
                },

                /**
                 * Destroy reCaptcha instance.
                 */
                destroy: function (widgetId) {
                    delete instances[widgetId];
                }
            };

        }];
    });

}(angular));
<|endoftext|>