<commit_before>/**!
 * AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
 * progress, resize, thumbnail, preview, validation and CORS
 * @author  Danial  <danial.farid@gmail.com>
 * @version <%= pkg.version %>
 */

if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
  window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
    return function (header, value) {
      if (header === '__setXHR_') {
        var val = value(this);
        // fix for angular < 1.2.0
        if (val instanceof Function) {
          val(this);
        }
      } else {
        orig.apply(this, arguments);
      }
    };
  })(window.XMLHttpRequest.prototype.setRequestHeader);
}

var ngFileUpload = angular.module('ngFileUpload', []);

ngFileUpload.version = '<%= pkg.version %>';

ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
  var upload = this;

  this.isResumeSupported = function () {
    return window.Blob && (Blob instanceof Function) && new Blob().slice;
  };

  var resumeSupported = this.isResumeSupported();

  function sendHttp(config) {
    config.method = config.method || 'POST';
    config.headers = config.headers || {};

    var deferred = config._deferred = config._deferred || $q.defer();
    var promise = deferred.promise;

    function notifyProgress(e) {
      if (deferred.notify) {
        deferred.notify(e);
      }
      if (promise.progressFunc) {
        $timeout(function () {
          promise.progressFunc(e);
        });
      }
    }

    function getNotifyEvent(n) {
      if (config._start != null && resumeSupported) {
        return {
          loaded: n.loaded + config._start, total: config._file.size, type: n.type, config: config,
          lengthComputable: true, target: n.target
        };
      } else {
        return n;
      }
    }

    if (!config.disableProgress) {
      config.headers.__setXHR_ = function () {
        return function (xhr) {
          if (!xhr || !(xhr instanceof XMLHttpRequest)) return;
          config.__XHR = xhr;
          if (config.xhrFn) config.xhrFn(xhr);
          xhr.upload.addEventListener('progress', function (e) {
            e.config = config;
            notifyProgress(getNotifyEvent(e));
          }, false);
          //fix for firefox not firing upload progress end, also IE8-9
          xhr.upload.addEventListener('load', function (e) {
            if (e.lengthComputable) {
              e.config = config;
              notifyProgress(getNotifyEvent(e));
            }
          }, false);
        };
      };
    }

    function uploadWithAngular() {
      $http(config).then(function (r) {
        if (resumeSupported && config._chunkSize && !config._finished) {
          notifyProgress({loaded: config._end, total: config._file.size, config: config, type: 'progress'});
          upload.upload(config);
        } else {
          if (config._finished) delete config._finished;
          deferred.resolve(r);
        }
      }, function (e) {
        deferred.reject(e);
      }, function (n) {
        deferred.notify(n);
      });
    }

    if (!resumeSupported) {
      uploadWithAngular();
    } else if (config._chunkSize && config._end && !config._finished) {
      config._start = config._end;
      config._end += config._chunkSize;
      uploadWithAngular();
    } else if (config.resumeSizeUrl) {
      $http.get(config.resumeSizeUrl).then(function (resp) {
        if (config.resumeSizeResponseReader) {
          config._start = config.resumeSizeResponseReader(resp.data);
        } else {
          config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
        }
        if (config._chunkSize) {
          config._end = config._start + config._chunkSize;
        }
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else if (config.resumeSize) {
      config.resumeSize().then(function (size) {
        config._start = size;
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else {
      uploadWithAngular();
    }

    promise.success = function (fn) {
      promise.then(function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.error = function (fn) {
      promise.then(null, function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.progress = function (fn) {
      promise.progressFunc = fn;
      promise.then(null, null, function (n) {
        fn(n);
      });
      return promise;
    };
    promise.abort = promise.pause = function () {
      if (config.__XHR) {
        $timeout(function () {
          config.__XHR.abort();
        });
      }
      return promise;
    };
    promise.xhr = function (fn) {
      config.xhrFn = (function (origXhrFn) {
        return function () {
          if (origXhrFn) origXhrFn.apply(promise, arguments);
          fn.apply(promise, arguments);
        };
      })(config.xhrFn);
      return promise;
    };

    return promise;
  }

  this.rename = function (file, name) {
    file.ngfName = name;
    return file;
  };

  this.jsonBlob = function (val) {
    var blob = new Blob([val], {type: 'application/json'});
    blob._ngfBlob = true;
    return blob;
  };

  this.json = function (val) {
    return angular.toJson(val);
  };

  this.upload = function (config) {
    function isFile(file) {
      return file != null && file instanceof Blob || (file.flashId && file.name && file.size);
    }

    function toResumeFile(file, formData) {
      if (file._ngfBlob) return file;
      config._file = config._file || file;
      if (config._start != null && resumeSupported) {
        if (config._end && config._end >= file.size) {
          config._finished = true;
          config._end = file.size;
        }
        var slice = file.slice(config._start, config._end || file.size);
        slice.name = file.name;
        slice.ngfName = file.ngfName;
        if (config._chunkSize) {
          formData.append('_chunkSize', config._end - config._start);
          formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
          formData.append('_totalSize', config._file.size);
        }
        return slice;
      }
      return file;
    }

    function addFieldToFormData(formData, val, key) {
      if (val !== undefined) {
        if (angular.isDate(val)) {
          val = val.toISOString();
        }
        if (angular.isString(val)) {
          formData.append(key, val);
        } else if (isFile(val)) {
          var file = toResumeFile(val, formData);
          var split = key.split(',');
          if (split[1]) {
            file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
            key = split[0];
          }
          config._fileKey = config._fileKey || key;
          formData.append(key, file, file.ngfName || file.name);
        } else {
          if (angular.isObject(val)) {
            if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;

            val.$$ngfCircularDetection = true;
            try {
              for (var k in val) {
                if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
                  var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
                  if (val.length && parseInt(k) > -1) {
                    objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
                  }
                  addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
                }
              }
            } finally {
              delete val.$$ngfCircularDetection;
            }
          } else {
            formData.append(key, val);
          }
        }
      }
    }

    function digestConfig() {
      config._chunkSize = upload.translateScalars(config.resumeChunkSize);
      config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

      config.headers = config.headers || {};
      config.headers['Content-Type'] = undefined;
      config.transformRequest = config.transformRequest ?
        (angular.isArray(config.transformRequest) ?
          config.transformRequest : [config.transformRequest]) : [];
      config.transformRequest.push(function (data) {
        var formData = new FormData(), key;
        data = data || config.fields || {};
        if (config.file) {
          data.file = config.file;
        }
        for (key in data) {
          if (data.hasOwnProperty(key)) {
            var val = data[key];
            if (config.formDataAppender) {
              config.formDataAppender(formData, key, val);
            } else {
              addFieldToFormData(formData, val, key);
            }
          }
        }

        return formData;
      });
    }

    if (!config._isDigested) {
      config._isDigested = true;
      digestConfig();
    }

    return sendHttp(config);
  };

  this.http = function (config) {
    config.transformRequest = config.transformRequest || function (data) {
        if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof Blob) {
          return data;
        }
        return $http.defaults.transformRequest[0].apply(this, arguments);
      };
    config._chunkSize = upload.translateScalars(config.resumeChunkSize);
    config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

    return sendHttp(config);
  };

  this.translateScalars = function (str) {
    if (angular.isString(str)) {
      if (str.search(/kb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000);
      } else if (str.search(/mb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000000);
      } else if (str.search(/gb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000000000);
      } else if (str.search(/b/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/s/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/m/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 60);
      } else if (str.search(/h/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 3600);
      }
    }
    return str;
  };

  this.setDefaults = function (defaults) {
    this.defaults = defaults || {};
  };

  this.defaults = {};
  this.version = ngFileUpload.version;
}

]);
<commit_msg>Update upload.js<commit_after>/**!
 * AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
 * progress, resize, thumbnail, preview, validation and CORS
 * @author  Danial  <danial.farid@gmail.com>
 * @version <%= pkg.version %>
 */

if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
  window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
    return function (header, value) {
      if (header === '__setXHR_') {
        var val = value(this);
        // fix for angular < 1.2.0
        if (val instanceof Function) {
          val(this);
        }
      } else {
        orig.apply(this, arguments);
      }
    };
  })(window.XMLHttpRequest.prototype.setRequestHeader);
}

var ngFileUpload = angular.module('ngFileUpload', []);

ngFileUpload.version = '<%= pkg.version %>';

ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
  var upload = this;

  this.isResumeSupported = function () {
    return window.Blob && (Blob instanceof Function) && new Blob().slice;
  };

  var resumeSupported = this.isResumeSupported();

  function sendHttp(config) {
    config.method = config.method || 'POST';
    config.headers = config.headers || {};

    var deferred = config._deferred = config._deferred || $q.defer();
    var promise = deferred.promise;

    function notifyProgress(e) {
      if (deferred.notify) {
        deferred.notify(e);
      }
      if (promise.progressFunc) {
        $timeout(function () {
          promise.progressFunc(e);
        });
      }
    }

    function getNotifyEvent(n) {
      if (config._start != null && resumeSupported) {
        return {
          loaded: n.loaded + config._start, total: config._file.size, type: n.type, config: config,
          lengthComputable: true, target: n.target
        };
      } else {
        return n;
      }
    }

    if (!config.disableProgress) {
      config.headers.__setXHR_ = function () {
        return function (xhr) {
          if (!xhr || !(xhr instanceof XMLHttpRequest)) return;
          config.__XHR = xhr;
          if (config.xhrFn) config.xhrFn(xhr);
          xhr.upload.addEventListener('progress', function (e) {
            e.config = config;
            notifyProgress(getNotifyEvent(e));
          }, false);
          //fix for firefox not firing upload progress end, also IE8-9
          xhr.upload.addEventListener('load', function (e) {
            if (e.lengthComputable) {
              e.config = config;
              notifyProgress(getNotifyEvent(e));
            }
          }, false);
        };
      };
    }

    function uploadWithAngular() {
      $http(config).then(function (r) {
        if (resumeSupported && config._chunkSize && !config._finished) {
          notifyProgress({loaded: config._end, total: config._file.size, config: config, type: 'progress'});
          upload.upload(config);
        } else {
          if (config._finished) delete config._finished;
          deferred.resolve(r);
        }
      }, function (e) {
        deferred.reject(e);
      }, function (n) {
        deferred.notify(n);
      });
    }

    if (!resumeSupported) {
      uploadWithAngular();
    } else if (config._chunkSize && config._end && !config._finished) {
      config._start = config._end;
      config._end += config._chunkSize;
      uploadWithAngular();
    } else if (config.resumeSizeUrl) {
      $http.get(config.resumeSizeUrl).then(function (resp) {
        if (config.resumeSizeResponseReader) {
          config._start = config.resumeSizeResponseReader(resp.data);
        } else {
          config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
        }
        if (config._chunkSize) {
          config._end = config._start + config._chunkSize;
        }
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else if (config.resumeSize) {
      config.resumeSize().then(function (size) {
        config._start = size;
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else {
      uploadWithAngular();
    }

    promise.success = function (fn) {
      promise.then(function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.error = function (fn) {
      promise.then(null, function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.progress = function (fn) {
      promise.progressFunc = fn;
      promise.then(null, null, function (n) {
        fn(n);
      });
      return promise;
    };
    promise.abort = promise.pause = function () {
      if (config.__XHR) {
        $timeout(function () {
          config.__XHR.abort();
        });
      }
      return promise;
    };
    promise.xhr = function (fn) {
      config.xhrFn = (function (origXhrFn) {
        return function () {
          if (origXhrFn) origXhrFn.apply(promise, arguments);
          fn.apply(promise, arguments);
        };
      })(config.xhrFn);
      return promise;
    };

    return promise;
  }

  this.rename = function (file, name) {
    file.ngfName = name;
    return file;
  };

  this.jsonBlob = function (val) {
    var blob = new Blob([val], {type: 'application/json'});
    blob._ngfBlob = true;
    return blob;
  };

  this.json = function (val) {
    return angular.toJson(val);
  };

  this.upload = function (config) {
    function isFile(file) {
      return file != null && (file instanceof Blob || (file.flashId && file.name && file.size));
    }

    function toResumeFile(file, formData) {
      if (file._ngfBlob) return file;
      config._file = config._file || file;
      if (config._start != null && resumeSupported) {
        if (config._end && config._end >= file.size) {
          config._finished = true;
          config._end = file.size;
        }
        var slice = file.slice(config._start, config._end || file.size);
        slice.name = file.name;
        slice.ngfName = file.ngfName;
        if (config._chunkSize) {
          formData.append('_chunkSize', config._end - config._start);
          formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
          formData.append('_totalSize', config._file.size);
        }
        return slice;
      }
      return file;
    }

    function addFieldToFormData(formData, val, key) {
      if (val !== undefined) {
        if (angular.isDate(val)) {
          val = val.toISOString();
        }
        if (angular.isString(val)) {
          formData.append(key, val);
        } else if (isFile(val)) {
          var file = toResumeFile(val, formData);
          var split = key.split(',');
          if (split[1]) {
            file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
            key = split[0];
          }
          config._fileKey = config._fileKey || key;
          formData.append(key, file, file.ngfName || file.name);
        } else {
          if (angular.isObject(val)) {
            if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;

            val.$$ngfCircularDetection = true;
            try {
              for (var k in val) {
                if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
                  var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
                  if (val.length && parseInt(k) > -1) {
                    objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
                  }
                  addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
                }
              }
            } finally {
              delete val.$$ngfCircularDetection;
            }
          } else {
            formData.append(key, val);
          }
        }
      }
    }

    function digestConfig() {
      config._chunkSize = upload.translateScalars(config.resumeChunkSize);
      config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

      config.headers = config.headers || {};
      config.headers['Content-Type'] = undefined;
      config.transformRequest = config.transformRequest ?
        (angular.isArray(config.transformRequest) ?
          config.transformRequest : [config.transformRequest]) : [];
      config.transformRequest.push(function (data) {
        var formData = new FormData(), key;
        data = data || config.fields || {};
        if (config.file) {
          data.file = config.file;
        }
        for (key in data) {
          if (data.hasOwnProperty(key)) {
            var val = data[key];
            if (config.formDataAppender) {
              config.formDataAppender(formData, key, val);
            } else {
              addFieldToFormData(formData, val, key);
            }
          }
        }

        return formData;
      });
    }

    if (!config._isDigested) {
      config._isDigested = true;
      digestConfig();
    }

    return sendHttp(config);
  };

  this.http = function (config) {
    config.transformRequest = config.transformRequest || function (data) {
        if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof Blob) {
          return data;
        }
        return $http.defaults.transformRequest[0].apply(this, arguments);
      };
    config._chunkSize = upload.translateScalars(config.resumeChunkSize);
    config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

    return sendHttp(config);
  };

  this.translateScalars = function (str) {
    if (angular.isString(str)) {
      if (str.search(/kb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000);
      } else if (str.search(/mb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000000);
      } else if (str.search(/gb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1000000000);
      } else if (str.search(/b/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/s/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/m/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 60);
      } else if (str.search(/h/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 3600);
      }
    }
    return str;
  };

  this.setDefaults = function (defaults) {
    this.defaults = defaults || {};
  };

  this.defaults = {};
  this.version = ngFileUpload.version;
}

]);
<|endoftext|>


<commit_before>/**!
 * AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
 * progress, resize, thumbnail, preview, validation and CORS
 * @author  Danial  <danial.farid@gmail.com>
 * @version <%= pkg.version %>
 */

if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
  window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
    return function (header, value) {
      if (header === '__setXHR_') {
        var val = value(this);
        // fix for angular < 1.2.0
        if (val instanceof Function) {
          val(this);
        }
      } else {
        orig.apply(this, arguments);
      }
    };
  })(window.XMLHttpRequest.prototype.setRequestHeader);
}

var ngFileUpload = angular.module('ngFileUpload', []);

ngFileUpload.version = '<%= pkg.version %>';

ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
  var upload = this;
  upload.promisesCount = 0;

  this.isResumeSupported = function () {
    return window.Blob && window.Blob.prototype.slice;
  };

  var resumeSupported = this.isResumeSupported();

  function sendHttp(config) {
    config.method = config.method || 'POST';
    config.headers = config.headers || {};

    var deferred = config._deferred = config._deferred || $q.defer();
    var promise = deferred.promise;

    function notifyProgress(e) {
      if (deferred.notify) {
        deferred.notify(e);
      }
      if (promise.progressFunc) {
        $timeout(function () {
          promise.progressFunc(e);
        });
      }
    }

    function getNotifyEvent(n) {
      if (config._start != null && resumeSupported) {
        return {
          loaded: n.loaded + config._start,
          total: (config._file && config._file.size) || n.total,
          type: n.type, config: config,
          lengthComputable: true, target: n.target
        };
      } else {
        return n;
      }
    }

    if (!config.disableProgress) {
      config.headers.__setXHR_ = function () {
        return function (xhr) {
          if (!xhr || !xhr.upload || !xhr.upload.addEventListener) return;
          config.__XHR = xhr;
          if (config.xhrFn) config.xhrFn(xhr);
          xhr.upload.addEventListener('progress', function (e) {
            e.config = config;
            notifyProgress(getNotifyEvent(e));
          }, false);
          //fix for firefox not firing upload progress end, also IE8-9
          xhr.upload.addEventListener('load', function (e) {
            if (e.lengthComputable) {
              e.config = config;
              notifyProgress(getNotifyEvent(e));
            }
          }, false);
        };
      };
    }

    function uploadWithAngular() {
      $http(config).then(function (r) {
          if (resumeSupported && config._chunkSize && !config._finished && config._file) {
            notifyProgress({
                loaded: config._end,
                total: config._file && config._file.size,
                config: config, type: 'progress'
              }
            );
            upload.upload(config, true);
          } else {
            if (config._finished) delete config._finished;
            deferred.resolve(r);
          }
        }, function (e) {
          deferred.reject(e);
        }, function (n) {
          deferred.notify(n);
        }
      );
    }

    if (!resumeSupported) {
      uploadWithAngular();
    } else if (config._chunkSize && config._end && !config._finished) {
      config._start = config._end;
      config._end += config._chunkSize;
      uploadWithAngular();
    } else if (config.resumeSizeUrl) {
      $http.get(config.resumeSizeUrl).then(function (resp) {
        if (config.resumeSizeResponseReader) {
          config._start = config.resumeSizeResponseReader(resp.data);
        } else {
          config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
        }
        if (config._chunkSize) {
          config._end = config._start + config._chunkSize;
        }
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else if (config.resumeSize) {
      config.resumeSize().then(function (size) {
        config._start = size;
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else {
      if (config._chunkSize) {
        config._start = 0;
        config._end = config._start + config._chunkSize;
      }
      uploadWithAngular();
    }

    promise.success = function (fn) {
      promise.then(function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.error = function (fn) {
      promise.then(null, function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.progress = function (fn) {
      promise.progressFunc = fn;
      promise.then(null, null, function (n) {
        fn(n);
      });
      return promise;
    };
    promise.abort = promise.pause = function () {
      if (config.__XHR) {
        $timeout(function () {
          config.__XHR.abort();
        });
      }
      return promise;
    };
    promise.xhr = function (fn) {
      config.xhrFn = (function (origXhrFn) {
        return function () {
          if (origXhrFn) origXhrFn.apply(promise, arguments);
          fn.apply(promise, arguments);
        };
      })(config.xhrFn);
      return promise;
    };

    upload.promisesCount++;
    promise['finally'](function () {
      upload.promisesCount--;
    });
    return promise;
  }

  this.isUploadInProgress = function () {
    return upload.promisesCount > 0;
  };

  this.rename = function (file, name) {
    file.ngfName = name;
    return file;
  };

  this.jsonBlob = function (val) {
    if (val != null && !angular.isString(val)) {
      val = JSON.stringify(val);
    }
    var blob = new window.Blob([val], {type: 'application/json'});
    blob._ngfBlob = true;
    return blob;
  };

  this.json = function (val) {
    return angular.toJson(val);
  };

  function copy(obj) {
    var clone = {};
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        clone[key] = obj[key];
      }
    }
    return clone;
  }

  this.isFile = function (file) {
    return file != null && (file instanceof window.Blob || (file.flashId && file.name && file.size));
  };

  this.upload = function (config, internal) {
    function toResumeFile(file, formData) {
      if (file._ngfBlob) return file;
      config._file = config._file || file;
      if (config._start != null && resumeSupported) {
        if (config._end && config._end >= file.size) {
          config._finished = true;
          config._end = file.size;
        }
        var slice = file.slice(config._start, config._end || file.size);
        slice.name = file.name;
        slice.ngfName = file.ngfName;
        if (config._chunkSize) {
          formData.append('_chunkSize', config._chunkSize);
          formData.append('_currentChunkSize', config._end - config._start);
          formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
          formData.append('_totalSize', config._file.size);
        }
        return slice;
      }
      return file;
    }

    function addFieldToFormData(formData, val, key) {
      if (val !== undefined) {
        if (angular.isDate(val)) {
          val = val.toISOString();
        }
        if (angular.isString(val)) {
          formData.append(key, val);
        } else if (upload.isFile(val)) {
          var file = toResumeFile(val, formData);
          var split = key.split(',');
          if (split[1]) {
            file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
            key = split[0];
          }
          config._fileKey = config._fileKey || key;
          formData.append(key, file, file.ngfName || file.name);
        } else {
          if (angular.isObject(val)) {
            if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;

            val.$$ngfCircularDetection = true;
            try {
              for (var k in val) {
                if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
                  var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
                  if (val.length && parseInt(k) > -1) {
                    objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
                  }
                  addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
                }
              }
            } finally {
              delete val.$$ngfCircularDetection;
            }
          } else {
            formData.append(key, val);
          }
        }
      }
    }

    function digestConfig() {
      config._chunkSize = upload.translateScalars(config.resumeChunkSize);
      config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

      config.headers = config.headers || {};
      config.headers['Content-Type'] = undefined;
      config.transformRequest = config.transformRequest ?
        (angular.isArray(config.transformRequest) ?
          config.transformRequest : [config.transformRequest]) : [];
      config.transformRequest.push(function (data) {
        var formData = new window.FormData(), key;
        data = data || config.fields || {};
        if (config.file) {
          data.file = config.file;
        }
        for (key in data) {
          if (data.hasOwnProperty(key)) {
            var val = data[key];
            if (config.formDataAppender) {
              config.formDataAppender(formData, key, val);
            } else {
              addFieldToFormData(formData, val, key);
            }
          }
        }

        return formData;
      });
    }

    if (!internal) config = copy(config);
    if (!config._isDigested) {
      config._isDigested = true;
      digestConfig();
    }

    return sendHttp(config);
  };

  this.http = function (config) {
    config = copy(config);
    config.transformRequest = config.transformRequest || function (data) {
        if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof window.Blob) {
          return data;
        }
        return $http.defaults.transformRequest[0].apply(this, arguments);
      };
    config._chunkSize = upload.translateScalars(config.resumeChunkSize);
    config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

    return sendHttp(config);
  };

  this.translateScalars = function (str) {
    if (angular.isString(str)) {
      if (str.search(/kb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1024);
      } else if (str.search(/mb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1048576);
      } else if (str.search(/gb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1073741824);
      } else if (str.search(/b/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/s/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/m/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 60);
      } else if (str.search(/h/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 3600);
      }
    }
    return str;
  };

  this.urlToBlob = function(url) {
    var defer = $q.defer();
    $http({url: url, method: 'get', responseType: 'arraybuffer'}).then(function (resp) {
      var arrayBufferView = new Uint8Array(resp.data);
      var type = resp.headers('content-type') || 'image/WebP';
      var blob = new window.Blob([arrayBufferView], {type: type});
      defer.resolve(blob);
      //var split = type.split('[/;]');
      //blob.name = url.substring(0, 150).replace(/\W+/g, '') + '.' + (split.length > 1 ? split[1] : 'jpg');
    }, function (e) {
      defer.reject(e);
    });
    return defer.promise;
  };

  this.setDefaults = function (defaults) {
    this.defaults = defaults || {};
  };

  this.defaults = {};
  this.version = ngFileUpload.version;
}

]);
<commit_msg>Fix end parameter in resumeSize promise<commit_after>/**!
 * AngularJS file upload directives and services. Supoorts: file upload/drop/paste, resume, cancel/abort,
 * progress, resize, thumbnail, preview, validation and CORS
 * @author  Danial  <danial.farid@gmail.com>
 * @version <%= pkg.version %>
 */

if (window.XMLHttpRequest && !(window.FileAPI && FileAPI.shouldLoad)) {
  window.XMLHttpRequest.prototype.setRequestHeader = (function (orig) {
    return function (header, value) {
      if (header === '__setXHR_') {
        var val = value(this);
        // fix for angular < 1.2.0
        if (val instanceof Function) {
          val(this);
        }
      } else {
        orig.apply(this, arguments);
      }
    };
  })(window.XMLHttpRequest.prototype.setRequestHeader);
}

var ngFileUpload = angular.module('ngFileUpload', []);

ngFileUpload.version = '<%= pkg.version %>';

ngFileUpload.service('UploadBase', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {
  var upload = this;
  upload.promisesCount = 0;

  this.isResumeSupported = function () {
    return window.Blob && window.Blob.prototype.slice;
  };

  var resumeSupported = this.isResumeSupported();

  function sendHttp(config) {
    config.method = config.method || 'POST';
    config.headers = config.headers || {};

    var deferred = config._deferred = config._deferred || $q.defer();
    var promise = deferred.promise;

    function notifyProgress(e) {
      if (deferred.notify) {
        deferred.notify(e);
      }
      if (promise.progressFunc) {
        $timeout(function () {
          promise.progressFunc(e);
        });
      }
    }

    function getNotifyEvent(n) {
      if (config._start != null && resumeSupported) {
        return {
          loaded: n.loaded + config._start,
          total: (config._file && config._file.size) || n.total,
          type: n.type, config: config,
          lengthComputable: true, target: n.target
        };
      } else {
        return n;
      }
    }

    if (!config.disableProgress) {
      config.headers.__setXHR_ = function () {
        return function (xhr) {
          if (!xhr || !xhr.upload || !xhr.upload.addEventListener) return;
          config.__XHR = xhr;
          if (config.xhrFn) config.xhrFn(xhr);
          xhr.upload.addEventListener('progress', function (e) {
            e.config = config;
            notifyProgress(getNotifyEvent(e));
          }, false);
          //fix for firefox not firing upload progress end, also IE8-9
          xhr.upload.addEventListener('load', function (e) {
            if (e.lengthComputable) {
              e.config = config;
              notifyProgress(getNotifyEvent(e));
            }
          }, false);
        };
      };
    }

    function uploadWithAngular() {
      $http(config).then(function (r) {
          if (resumeSupported && config._chunkSize && !config._finished && config._file) {
            notifyProgress({
                loaded: config._end,
                total: config._file && config._file.size,
                config: config, type: 'progress'
              }
            );
            upload.upload(config, true);
          } else {
            if (config._finished) delete config._finished;
            deferred.resolve(r);
          }
        }, function (e) {
          deferred.reject(e);
        }, function (n) {
          deferred.notify(n);
        }
      );
    }

    if (!resumeSupported) {
      uploadWithAngular();
    } else if (config._chunkSize && config._end && !config._finished) {
      config._start = config._end;
      config._end += config._chunkSize;
      uploadWithAngular();
    } else if (config.resumeSizeUrl) {
      $http.get(config.resumeSizeUrl).then(function (resp) {
        if (config.resumeSizeResponseReader) {
          config._start = config.resumeSizeResponseReader(resp.data);
        } else {
          config._start = parseInt((resp.data.size == null ? resp.data : resp.data.size).toString());
        }
        if (config._chunkSize) {
          config._end = config._start + config._chunkSize;
        }
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else if (config.resumeSize) {
      config.resumeSize().then(function (size) {
        config._start = size;
        if (config._chunkSize) {
          config._end = config._start + config._chunkSize;
        }
        uploadWithAngular();
      }, function (e) {
        throw e;
      });
    } else {
      if (config._chunkSize) {
        config._start = 0;
        config._end = config._start + config._chunkSize;
      }
      uploadWithAngular();
    }

    promise.success = function (fn) {
      promise.then(function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.error = function (fn) {
      promise.then(null, function (response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.progress = function (fn) {
      promise.progressFunc = fn;
      promise.then(null, null, function (n) {
        fn(n);
      });
      return promise;
    };
    promise.abort = promise.pause = function () {
      if (config.__XHR) {
        $timeout(function () {
          config.__XHR.abort();
        });
      }
      return promise;
    };
    promise.xhr = function (fn) {
      config.xhrFn = (function (origXhrFn) {
        return function () {
          if (origXhrFn) origXhrFn.apply(promise, arguments);
          fn.apply(promise, arguments);
        };
      })(config.xhrFn);
      return promise;
    };

    upload.promisesCount++;
    promise['finally'](function () {
      upload.promisesCount--;
    });
    return promise;
  }

  this.isUploadInProgress = function () {
    return upload.promisesCount > 0;
  };

  this.rename = function (file, name) {
    file.ngfName = name;
    return file;
  };

  this.jsonBlob = function (val) {
    if (val != null && !angular.isString(val)) {
      val = JSON.stringify(val);
    }
    var blob = new window.Blob([val], {type: 'application/json'});
    blob._ngfBlob = true;
    return blob;
  };

  this.json = function (val) {
    return angular.toJson(val);
  };

  function copy(obj) {
    var clone = {};
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        clone[key] = obj[key];
      }
    }
    return clone;
  }

  this.isFile = function (file) {
    return file != null && (file instanceof window.Blob || (file.flashId && file.name && file.size));
  };

  this.upload = function (config, internal) {
    function toResumeFile(file, formData) {
      if (file._ngfBlob) return file;
      config._file = config._file || file;
      if (config._start != null && resumeSupported) {
        if (config._end && config._end >= file.size) {
          config._finished = true;
          config._end = file.size;
        }
        var slice = file.slice(config._start, config._end || file.size);
        slice.name = file.name;
        slice.ngfName = file.ngfName;
        if (config._chunkSize) {
          formData.append('_chunkSize', config._chunkSize);
          formData.append('_currentChunkSize', config._end - config._start);
          formData.append('_chunkNumber', Math.floor(config._start / config._chunkSize));
          formData.append('_totalSize', config._file.size);
        }
        return slice;
      }
      return file;
    }

    function addFieldToFormData(formData, val, key) {
      if (val !== undefined) {
        if (angular.isDate(val)) {
          val = val.toISOString();
        }
        if (angular.isString(val)) {
          formData.append(key, val);
        } else if (upload.isFile(val)) {
          var file = toResumeFile(val, formData);
          var split = key.split(',');
          if (split[1]) {
            file.ngfName = split[1].replace(/^\s+|\s+$/g, '');
            key = split[0];
          }
          config._fileKey = config._fileKey || key;
          formData.append(key, file, file.ngfName || file.name);
        } else {
          if (angular.isObject(val)) {
            if (val.$$ngfCircularDetection) throw 'ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: ' + key;

            val.$$ngfCircularDetection = true;
            try {
              for (var k in val) {
                if (val.hasOwnProperty(k) && k !== '$$ngfCircularDetection') {
                  var objectKey = config.objectKey == null ? '[i]' : config.objectKey;
                  if (val.length && parseInt(k) > -1) {
                    objectKey = config.arrayKey == null ? objectKey : config.arrayKey;
                  }
                  addFieldToFormData(formData, val[k], key + objectKey.replace(/[ik]/g, k));
                }
              }
            } finally {
              delete val.$$ngfCircularDetection;
            }
          } else {
            formData.append(key, val);
          }
        }
      }
    }

    function digestConfig() {
      config._chunkSize = upload.translateScalars(config.resumeChunkSize);
      config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

      config.headers = config.headers || {};
      config.headers['Content-Type'] = undefined;
      config.transformRequest = config.transformRequest ?
        (angular.isArray(config.transformRequest) ?
          config.transformRequest : [config.transformRequest]) : [];
      config.transformRequest.push(function (data) {
        var formData = new window.FormData(), key;
        data = data || config.fields || {};
        if (config.file) {
          data.file = config.file;
        }
        for (key in data) {
          if (data.hasOwnProperty(key)) {
            var val = data[key];
            if (config.formDataAppender) {
              config.formDataAppender(formData, key, val);
            } else {
              addFieldToFormData(formData, val, key);
            }
          }
        }

        return formData;
      });
    }

    if (!internal) config = copy(config);
    if (!config._isDigested) {
      config._isDigested = true;
      digestConfig();
    }

    return sendHttp(config);
  };

  this.http = function (config) {
    config = copy(config);
    config.transformRequest = config.transformRequest || function (data) {
        if ((window.ArrayBuffer && data instanceof window.ArrayBuffer) || data instanceof window.Blob) {
          return data;
        }
        return $http.defaults.transformRequest[0].apply(this, arguments);
      };
    config._chunkSize = upload.translateScalars(config.resumeChunkSize);
    config._chunkSize = config._chunkSize ? parseInt(config._chunkSize.toString()) : null;

    return sendHttp(config);
  };

  this.translateScalars = function (str) {
    if (angular.isString(str)) {
      if (str.search(/kb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1024);
      } else if (str.search(/mb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1048576);
      } else if (str.search(/gb/i) === str.length - 2) {
        return parseFloat(str.substring(0, str.length - 2) * 1073741824);
      } else if (str.search(/b/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/s/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1));
      } else if (str.search(/m/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 60);
      } else if (str.search(/h/i) === str.length - 1) {
        return parseFloat(str.substring(0, str.length - 1) * 3600);
      }
    }
    return str;
  };

  this.urlToBlob = function(url) {
    var defer = $q.defer();
    $http({url: url, method: 'get', responseType: 'arraybuffer'}).then(function (resp) {
      var arrayBufferView = new Uint8Array(resp.data);
      var type = resp.headers('content-type') || 'image/WebP';
      var blob = new window.Blob([arrayBufferView], {type: type});
      defer.resolve(blob);
      //var split = type.split('[/;]');
      //blob.name = url.substring(0, 150).replace(/\W+/g, '') + '.' + (split.length > 1 ? split[1] : 'jpg');
    }, function (e) {
      defer.reject(e);
    });
    return defer.promise;
  };

  this.setDefaults = function (defaults) {
    this.defaults = defaults || {};
  };

  this.defaults = {};
  this.version = ngFileUpload.version;
}

]);
<|endoftext|>


<commit_before>import test from 'ava';
import Heap from '../';

test('should leave a valid tree on a flat Fibonacci heap', function (t) {
  var heap = new Heap();
  heap.insert(13, null);
  heap.insert(26, null);
  heap.insert(3, null);
  heap.insert(-6, null);
  heap.insert(27, null);
  var node6 = heap.insert(88, null);
  heap.insert(59, null);
  heap.insert(-10, null);
  heap.insert(16, null);
  heap.decreaseKey(node6, -8);
  t.deepEqual(heap.extractMinimum().key, -10);
  t.deepEqual(heap.extractMinimum().key, -8);
  t.deepEqual(heap.extractMinimum().key, -6);
  t.deepEqual(heap.extractMinimum().key, 3);
  t.deepEqual(heap.extractMinimum().key, 13);
  t.deepEqual(heap.extractMinimum().key, 16);
  t.deepEqual(heap.extractMinimum().key, 26);
  t.deepEqual(heap.extractMinimum().key, 27);
  t.deepEqual(heap.extractMinimum().key, 59);
});

test('should leave a valid tree on a consolidated Fibonacci heap', function (t) {
  var heap = new Heap();
  var node0 = heap.insert(0, null);
  var node1 = heap.insert(1, null);
  var node2 = heap.insert(2, null);
  var node3 = heap.insert(3, null);
  var node4 = heap.insert(4, null);
  var node5 = heap.insert(5, null);
  var node6 = heap.insert(6, null);
  var node7 = heap.insert(7, null);
  var node8 = heap.insert(8, null);

  // Extracting minimum should trigger consolidate.
  //
  //                                    __1
  //                                   / /|
  //                                  5 3 2
  //  0--1--2--3--4--5--6--7--8  ->  /| |
  //                                7 6 4
  //                                |
  //                                8
  //
  t.is(heap.extractMinimum(), node0);

  // Decrease node 8 to 0
  //
  //      __1
  //     / /|        __1--0
  //    5 3 2       / /|
  //   /| |    ->  5 3 2
  //  7 6 4       /| |
  //  |          7 6 4
  //  8
  //
  heap.decreaseKey(node8, 0);
  t.true(node1.next === node8);

  t.is(heap.size(), 8);
  t.true(heap.extractMinimum() === node8);
  t.true(heap.extractMinimum() === node1);
  t.true(heap.extractMinimum() === node2);
  t.true(heap.extractMinimum() === node3);
  t.true(heap.extractMinimum() === node4);
  t.true(heap.extractMinimum() === node5);
  t.true(heap.extractMinimum() === node6);
  t.true(heap.extractMinimum() === node7);
  t.true(heap.isEmpty());
});
<commit_msg>Add test case for cut removing the node's parent<commit_after>import test from 'ava';
import Heap from '../';

test('should leave a valid tree on a flat Fibonacci heap', function (t) {
  var heap = new Heap();
  heap.insert(13, null);
  heap.insert(26, null);
  heap.insert(3, null);
  heap.insert(-6, null);
  heap.insert(27, null);
  var node6 = heap.insert(88, null);
  heap.insert(59, null);
  heap.insert(-10, null);
  heap.insert(16, null);
  heap.decreaseKey(node6, -8);
  t.deepEqual(heap.extractMinimum().key, -10);
  t.deepEqual(heap.extractMinimum().key, -8);
  t.deepEqual(heap.extractMinimum().key, -6);
  t.deepEqual(heap.extractMinimum().key, 3);
  t.deepEqual(heap.extractMinimum().key, 13);
  t.deepEqual(heap.extractMinimum().key, 16);
  t.deepEqual(heap.extractMinimum().key, 26);
  t.deepEqual(heap.extractMinimum().key, 27);
  t.deepEqual(heap.extractMinimum().key, 59);
});

test('should leave a valid tree on a consolidated Fibonacci heap', function (t) {
  var heap = new Heap();
  var node0 = heap.insert(0, null);
  var node1 = heap.insert(1, null);
  var node2 = heap.insert(2, null);
  var node3 = heap.insert(3, null);
  var node4 = heap.insert(4, null);
  var node5 = heap.insert(5, null);
  var node6 = heap.insert(6, null);
  var node7 = heap.insert(7, null);
  var node8 = heap.insert(8, null);

  // Extracting minimum should trigger consolidate.
  //
  //                                    __1
  //                                   / /|
  //                                  5 3 2
  //  0--1--2--3--4--5--6--7--8  ->  /| |
  //                                7 6 4
  //                                |
  //                                8
  //
  t.is(heap.extractMinimum(), node0);

  // Decrease node 8 to 0
  //
  //      __1
  //     / /|        __1--0
  //    5 3 2       / /|
  //   /| |    ->  5 3 2
  //  7 6 4       /| |
  //  |          7 6 4
  //  8
  //
  heap.decreaseKey(node8, 0);
  t.true(node1.next === node8);

  t.is(heap.size(), 8);
  t.true(heap.extractMinimum() === node8);
  t.true(heap.extractMinimum() === node1);
  t.true(heap.extractMinimum() === node2);
  t.true(heap.extractMinimum() === node3);
  t.true(heap.extractMinimum() === node4);
  t.true(heap.extractMinimum() === node5);
  t.true(heap.extractMinimum() === node6);
  t.true(heap.extractMinimum() === node7);
  t.true(heap.isEmpty());
});

test('should delete the node\'s parent reference after a cut', function (t) {
  var heap = new Heap();
  var node1 = heap.insert(1, null);
  var node2 = heap.insert(2, null);
  var node3 = heap.insert(3, null);
  t.is(heap.size(), 3);

  // Trigger a consolidate
  //
  //               2
  //  1--2--3  ->  |
  //               3
  //
  t.is(heap.extractMinimum(), node1);

  // Decrease 3's key such that it's less than its parent
  //
  //  2      1
  //  |  ->  |
  //  3      2
  //
  heap.decreaseKey(node3, 1);

  // Ensure 1's parent is undefined (the link to 2 has been cut)
  t.is(node3.parent, undefined);
});
<|endoftext|>


<commit_before>'use strict';

function Followers(nodecg) {
  this.nodecg = nodecg;
  this.request = require('request');
  this.latestFollower = nodecg.Replicant('latestFollower', { defaultValue: null, persistent: true });
  this.username = nodecg.bundleConfig.username;
  this.pollInterval = nodecg.bundleConfig.pollInterval * 1000;

  this._scheduleFollowers();
}

Followers.prototype._scheduleFollowers = function() {
  this.nodecg.log.debug('Polling for TwitchTV Followers.');
  this.request('https://api.twitch.tv/kraken/channels/' + this.username + '/follows?limit=50',
    (err, response, body) => {
      if (err) {
        this.nodecg.log.error(err);
        setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
        return;
      }
      if (response.statusCode != 200) {
        this.nodecg.log.error('Unknown response code: ' + response.statusCode);
        setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
        return;
      }

      var lastFollowerTs = 0;
      if (this.latestFollower.value) {
        lastFollowerTs = Date.parse(this.latestFollower.value.created_at);
      }

      try {
        body = JSON.parse(body);
      } catch (error) {
        this.nodecg.log.error(error);
        return;
      }

      if (body.follows.length > 0) {
        this.nodecg.log.debug('Discovered ' + body.follows.length + ' followers.');
        this.latestFollower.value = body.follows[0];

        body.follows.reverse().map((follower) => {
          var parsedTs = Date.parse(follower.created_at);
          if (parsedTs > lastFollowerTs) {
            this.nodecg.sendMessage('follower', follower);
          }
        });
      }

      setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
    }
  );
};

module.exports = function(api) {
  return new Followers(api);
};
<commit_msg>update extension.js for aug. 8 twitch changes<commit_after>'use strict';

function Followers(nodecg) {
  this.nodecg = nodecg;
  this.request = require('request');
  this.latestFollower = nodecg.Replicant('latestFollower', { defaultValue: null, persistent: true });
  this.username = nodecg.bundleConfig.username;
  this.pollInterval = nodecg.bundleConfig.pollInterval * 1000;

  this._scheduleFollowers();
}

Followers.prototype._scheduleFollowers = function() {
  var options = {
		url: 'https://api.twitch.tv/kraken/channels/' + this.username + '/follows?limit=50',
		headers: {
			'Client-ID': this.nodecg.config.login.twitch.clientID
		}
	};
  this.nodecg.log.debug('Polling for TwitchTV Followers.');
  this.request(options,
    (err, response, body) => {
      if (err) {
        this.nodecg.log.error(err);
        setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
        return;
      }
      if (response.statusCode != 200) {
        this.nodecg.log.error('Unknown response code: ' + response.statusCode);
        setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
        return;
      }

      var lastFollowerTs = 0;
      if (this.latestFollower.value) {
        lastFollowerTs = Date.parse(this.latestFollower.value.created_at);
      }

      try {
        body = JSON.parse(body);
      } catch (error) {
        this.nodecg.log.error(error);
        return;
      }

      if (body.follows.length > 0) {
        this.nodecg.log.debug('Discovered ' + body.follows.length + ' followers.');
        this.latestFollower.value = body.follows[0];

        body.follows.reverse().map((follower) => {
          var parsedTs = Date.parse(follower.created_at);
          if (parsedTs > lastFollowerTs) {
            this.nodecg.sendMessage('follower', follower);
          }
        });
      }

      setTimeout(() => { this._scheduleFollowers(); }, this.pollInterval);
    }
  );
};

module.exports = function(api) {
  return new Followers(api);
};
<|endoftext|>


<commit_before>/* Copyright (c) 2013-2016 The TagSpaces Authors.
 * Use of this source code is governed by the MIT license which can be found in the LICENSE.txt file. */

define(function(require, exports, module) {
  "use strict";

  var extensionID = "editorHTML"; // ID should be equal to the directory name where the ext. is located
  var extensionSupportedFileTypes = ["html", "htm"];

  console.log("Loading " + extensionID);

  var TSCORE = require("tscore");
  var extensionsPath = TSCORE.Config.getExtensionPath();
  var extensionDirectory = extensionsPath + "/" + extensionID;
  var fileDirectory;
  var currentContent;
  var currentFilePath;
  var $containerElement;
  var contentVersion = 0;
  var sourceURL = "";
  var scrappedOn = "";

  function init(filePath, containerElementID) {
    console.log("Initalization HTML Editor...");

    fileDirectory = TSCORE.TagUtils.extractContainingDirectoryPath(filePath);

    $containerElement = $('#' + containerElementID);

    currentFilePath = filePath;

    $containerElement.empty();
    $containerElement.css("background-color", "white");

    var extPath = extensionDirectory + "/index.html";
    $containerElement.append($('', {
      id: "iframeViewer",
      sandbox: "allow-same-origin allow-scripts allow-modals",
      scrolling: "no",
      style: "background-color: white; overflow: hidden;",
      src: extPath + "?cp=" + filePath + "&setLng=" + TSCORE.currentLanguage,
      "nwdisable": "",
      "nwfaketop": ""
    }));

    TSCORE.IO.loadTextFilePromise(filePath).then(function(content) {
              //TSPOSTIO.loadTextFile(content);
              exports.setContent(content);
            },
            function(error) {
              TSCORE.hideLoadingAnimation();
              TSCORE.showAlertDialog("Loading " + filePath + " failed.");
              console.error("Loading file " + filePath + " failed " + error);
            }
    );
  }

  function setFileType(fileType) {

    console.log("setFileType not supported on this extension");
  }

  function viewerMode(isViewerMode) {
    // set readonly
    console.log("viewerMode not supported on this extension");
  }

  function setContent(content) {
    currentContent = content;

    var bodyContent;
    var cleanedBodyContent;
    var bodyRegex = /\]*\>([^]*)\<\/body/m; // jshint ignore:line

    if (content.length > 3) {
      try {
        bodyContent = content.match(bodyRegex)[1];
      } catch (e) {
        console.log("Error parsing the body of the HTML document. " + e);
        bodyContent = content;
      }

      try {
        var scrappedOnRegex = /data-scrappedon='([^']*)'/m; // jshint ignore:line
        scrappedOn = content.match(scrappedOnRegex)[1];
      } catch (e) {
        console.log("Error parsing the meta from the HTML document. " + e);
      }

      try {
        var sourceURLRegex = /data-sourceurl='([^']*)'/m; // jshint ignore:line
        sourceURL = content.match(sourceURLRegex)[1];
      } catch (e) {
        console.log("Error parsing the meta from the HTML document. " + e);
      }

      //var titleRegex = /\<title[^>]*\>([^]*)\<\/title/m;
      //var titleContent = content.match( titleRegex )[1];

      // removing all scripts from the document
    } else {
      currentContent = TSCORE.Config.DefaultSettings.newHTMLFileContent;
      bodyContent = currentContent.match(bodyRegex)[1];
    }
    cleanedBodyContent = bodyContent.replace(/


<commit_before>"use strict";

var vscode = require('vscode');

function activate(context) {
    console.log('highlight-words is activated');
    var words = [];
    vscode.commands.registerCommand('extension.addRegExpHighlight', function () {
        vscode.window.showInputBox({prompt: 'Enter expression'})
            .then(word => {
                try {
                    new RegExp(word)
                    if (!~words.indexOf(word)) {
                        words.push(word);
                        updateDecorations();
                    }
                } catch (e) {
                    vscode.window.showInformationMessage(word + ' is an invalid expression')
                }
            });
    });

    vscode.commands.registerCommand('extension.addHighlight', function () {
        var editor = vscode.window.activeTextEditor;
        var word = editor.document.getText(editor.selection);
        if (!word) {
            vscode.window.showInformationMessage('Nothing selected!');
            return;
        }
        word = word.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") // raw selected text, not regexp
        if (!~words.indexOf(word)) {
            words.push(word);
            updateDecorations();
        }
    });

    vscode.commands.registerCommand('extension.removeHighlight', function () {
        vscode.window.showQuickPick(words.concat(['* All *']))
            .then(word => {
                if(!word) return;
                if(word == '* All *') words = [];
                else words.splice(words.indexOf(word), 1);
                updateDecorations();
            })
    });

    var colors = [
        { light: '#b3d9ff', dark: 'cyan' },
        { light: '#e6ffb3', dark: 'pink' },
        { light: '#b3b3ff', dark: 'lightgreen' },
        { light: '#ffd9b3', dark: 'magenta' },
        { light: '#ffb3ff', dark: 'cornflowerblue' },
        { light: '#b3ffb3', dark: 'orange' },
        { light: '#ffff80', dark: 'green' },
        { light: '#d1e0e0', dark: 'red' },
    ];
    var decorators = [];
    colors.forEach(function (color) {
        var decorationType = vscode.window.createTextEditorDecorationType({
            borderWidth: '2px',
            borderStyle: 'solid',
            overviewRulerColor: color.dark,
            overviewRulerLane: vscode.OverviewRulerLane.Right,
            light: {
                // this color will be used in light color themes
                borderColor: color.light,
                backgroundColor: color.light
            },
            dark: {
                // this color will be used in dark color themes
                borderColor: color.dark
            }
        });
        decorators.push(decorationType);
    });
    var activeEditor = vscode.window.activeTextEditor;
    if (activeEditor) {
        triggerUpdateDecorations();
    }
    vscode.window.onDidChangeActiveTextEditor(function (editor) {
        activeEditor = editor;
        if (editor) {
            updateDecorations();
        }
    }, null, context.subscriptions);
    vscode.workspace.onDidChangeTextDocument(function (event) {
        if (activeEditor && event.document === activeEditor.document) {
            triggerUpdateDecorations();
        }
    }, null, context.subscriptions);
    var timeout = null;
    function triggerUpdateDecorations() {
        if (timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(updateDecorations, 500);
    }

    function updateDecorations() {
        if (!activeEditor) {
            return;
        }

        vscode.window.visibleTextEditors.forEach(editor => {
            var text = editor.document.getText();
            var match;
            var decs = [];
            decorators.forEach(function () {
                var dec = [];
                decs.push(dec);
            });
            console.log('highlight words', words);
            words.forEach(function (i, n) {
                var regEx = new RegExp(i, 'g');
                while (match = regEx.exec(text)) {
                    var startPos = editor.document.positionAt(match.index);
                    var endPos = editor.document.positionAt(match.index + match[0].length);
                    var decoration = { range: new vscode.Range(startPos, endPos)};
                    decs[n % decs.length].push(decoration);
                }
            });
            decorators.forEach(function (d, i) {
                editor.setDecorations(d, decs[i]);
            });

        })

    }
}
exports.activate = activate;
<commit_msg>Removed console.log<commit_after>"use strict";

var vscode = require('vscode');

function activate(context) {
    var words = [];
    vscode.commands.registerCommand('extension.addRegExpHighlight', function () {
        vscode.window.showInputBox({prompt: 'Enter expression'})
            .then(word => {
                try {
                    new RegExp(word)
                    if (!~words.indexOf(word)) {
                        words.push(word);
                        updateDecorations();
                    }
                } catch (e) {
                    vscode.window.showInformationMessage(word + ' is an invalid expression')
                }
            });
    });

    vscode.commands.registerCommand('extension.addHighlight', function () {
        var editor = vscode.window.activeTextEditor;
        var word = editor.document.getText(editor.selection);
        if (!word) {
            vscode.window.showInformationMessage('Nothing selected!');
            return;
        }
        word = word.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") // raw selected text, not regexp
        if (!~words.indexOf(word)) {
            words.push(word);
            updateDecorations();
        }
    });

    vscode.commands.registerCommand('extension.removeHighlight', function () {
        vscode.window.showQuickPick(words.concat(['* All *']))
            .then(word => {
                if(!word) return;
                if(word == '* All *') words = [];
                else words.splice(words.indexOf(word), 1);
                updateDecorations();
            })
    });

    var colors = [
        { light: '#b3d9ff', dark: 'cyan' },
        { light: '#e6ffb3', dark: 'pink' },
        { light: '#b3b3ff', dark: 'lightgreen' },
        { light: '#ffd9b3', dark: 'magenta' },
        { light: '#ffb3ff', dark: 'cornflowerblue' },
        { light: '#b3ffb3', dark: 'orange' },
        { light: '#ffff80', dark: 'green' },
        { light: '#d1e0e0', dark: 'red' },
    ];
    var decorators = [];
    colors.forEach(function (color) {
        var decorationType = vscode.window.createTextEditorDecorationType({
            borderWidth: '2px',
            borderStyle: 'solid',
            overviewRulerColor: color.dark,
            overviewRulerLane: vscode.OverviewRulerLane.Right,
            light: {
                // this color will be used in light color themes
                borderColor: color.light,
                backgroundColor: color.light
            },
            dark: {
                // this color will be used in dark color themes
                borderColor: color.dark
            }
        });
        decorators.push(decorationType);
    });
    var activeEditor = vscode.window.activeTextEditor;
    if (activeEditor) {
        triggerUpdateDecorations();
    }
    vscode.window.onDidChangeActiveTextEditor(function (editor) {
        activeEditor = editor;
        if (editor) {
            updateDecorations();
        }
    }, null, context.subscriptions);
    vscode.workspace.onDidChangeTextDocument(function (event) {
        if (activeEditor && event.document === activeEditor.document) {
            triggerUpdateDecorations();
        }
    }, null, context.subscriptions);
    var timeout = null;
    function triggerUpdateDecorations() {
        if (timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(updateDecorations, 500);
    }

    function updateDecorations() {
        if (!activeEditor) {
            return;
        }

        vscode.window.visibleTextEditors.forEach(editor => {
            var text = editor.document.getText();
            var match;
            var decs = [];
            decorators.forEach(function () {
                var dec = [];
                decs.push(dec);
            });
            words.forEach(function (i, n) {
                var regEx = new RegExp(i, 'g');
                while (match = regEx.exec(text)) {
                    var startPos = editor.document.positionAt(match.index);
                    var endPos = editor.document.positionAt(match.index + match[0].length);
                    var decoration = { range: new vscode.Range(startPos, endPos)};
                    decs[n % decs.length].push(decoration);
                }
            });
            decorators.forEach(function (d, i) {
                editor.setDecorations(d, decs[i]);
            });

        })

    }
}
exports.activate = activate;
<|endoftext|>


<commit_before>'use strict'

function activate(context) {
    return {
        extendMarkdownIt(md) {
            return md.use(require('markdown-it-emoji'));
        }
    };
}
exports.activate = activate;
<commit_msg>TS Check and remove unused<commit_after>//@ts-check
'use strict'

function activate() {
    return {
        extendMarkdownIt(md) {
            return md.use(require('markdown-it-emoji'));
        }
    };
}
exports.activate = activate;
<|endoftext|>


<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets */

/**
* Brackets Link File Watcher.
*/
define(function Watcher(require, exports, module) {
    'use strict';

    var EditorManager   = brackets.getModule("editor/EditorManager"),
        LanguageManager = brackets.getModule("language/LanguageManager"),
        FileUtils       = brackets.getModule("file/FileUtils"),
        ProjectManager  = brackets.getModule("project/ProjectManager");

    var Linker          = require("./linker");

    // Regexps
    var REGEXPS = {
        'javascript':   /<script\b[^>]*>([\s\S]*?)<\/script>/g,
        'image':        [/<img\b[^>]*>([\s\S]*?)>{0}/g, /url([\s\S]*?).*;{0}/g],
        'css':          /<link\b[^>]*>([\s\S]*?)>{0}/g,
        'php':          /[include|include_once|require|require_once]([\s\S]*?).*;{0}/g,
        'audio':        /<audio\b[^>]*>([\s\S]*?)<\/audio>/g,
        'video':        /<video\b[^>]*>([\s\S]*?)<\/video>/g
    };

    var VIDEO_EXTENSIONS = ['mp4', 'ogg', 'ogv', 'webm'];

    // Project files storages
    var _watchedFiles = [],
        _watchedFilesCache = [];

    // Watcher functions
    var _intervalFunc,
        _projectChangeFunc;

    /**
     * Compares cached project files with current.
     * @private
     * @returns {Array} Full path strings of removed files.
     */
    function _compareFiles() {
        var removedFiles = [];
        _watchedFilesCache.forEach(function (file) {
            if ($.inArray(file, _watchedFiles) === -1) {
                removedFiles.push(file.fullPath);
            }
        });
        return removedFiles;
    }

    /**
     * Removes matched links/tags from text.
     * @private
     * @param   {string} relPath  Relative path.
     * @param   {string} docText  Text of a document to be changed.
     * @param   {string} fileLang Language of the file link to be removed.
     * @returns {string} Text with links/tags removed.
     */
    function _removeLinks(relPath, docText, fileLang) {
        if (fileLang === "unknown" || fileLang === "binary") {
            var fileExt = FileUtils.getFileExtension(relPath);
            if ($.inArray(fileExt, VIDEO_EXTENSIONS) > -1) { fileLang = "video"; }
        }
        if (fileLang === "svg") { fileLang = "image"; }

        var regexp;
        if (fileLang === "image") {
            var editor = EditorManager. getActiveEditor();
            var docLang = editor.getLanguageForSelection().getId();
            if (docLang === "html") {
                regexp = REGEXPS[fileLang][0];
            } else {
                regexp = REGEXPS[fileLang][1];
            }
        } else {
            regexp = REGEXPS[fileLang];
        }

        var links = docText.match(regexp);
        if (links && links.length > 0) {
            links.forEach(function (link) {
                if (link.indexOf(relPath) !== -1) {
                    docText = docText.replace(link, "");
                }
            });
        }
        return docText;
    }

    /**
     * Starts the project files watcher.
     * Sets the scanning every two seconds for removed files and
     * remove links/tags, if any.
     */
    function start() {
        ProjectManager.getAllFiles().done(function (files) {
            _watchedFilesCache = files.slice(0);

            _intervalFunc = setInterval(function () {
                ProjectManager.getAllFiles().done(function (files) {
                    _watchedFiles = files.slice(0);
                    var removedFiles = _compareFiles();
                    if (removedFiles.length > 0) {
                        removedFiles.forEach(function (filePath) {
                            var editor = EditorManager. getActiveEditor();
                            if (editor) {
                                var fileLang = LanguageManager.getLanguageForPath(filePath).getId();
                                var relPath = Linker.findRelativePath(filePath, editor.getFile().fullPath);
                                var docText = editor.document.getText();
                                var newText = _removeLinks(relPath, docText, fileLang);
                                editor.document.replaceRange(
                                    newText,
                                    {line: 0, ch: 0},
                                    {line: 9999, ch: 9999}
                                );
                            }
                        });
                    }
                    _watchedFilesCache = files.slice(0);
                });
            }, 2000);

            ProjectManager.on("projectOpen.blfwatcher", function () {
                ProjectManager.getAllFiles().done(function (files) {
                    _watchedFilesCache = files.slice(0);
                });
            });
        });
    }

    /**
     * Stops the project files watcher.
     */
    function stop() {
        clearInterval(_intervalFunc);
        ProjectManager.off("projectOpen.blfwatcher");
    }

    module.exports = {
        start: start,
        stop: stop
    };
});
<commit_msg>Watcher: fix for not auto-refresh file tree in Windows.<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets */

/**
* Brackets Link File Watcher.
*/
define(function Watcher(require, exports, module) {
    'use strict';

    var EditorManager   = brackets.getModule("editor/EditorManager"),
        LanguageManager = brackets.getModule("language/LanguageManager"),
        FileUtils       = brackets.getModule("file/FileUtils"),
        ProjectManager  = brackets.getModule("project/ProjectManager");

    var Linker          = require("./linker");

    // Regexps
    var REGEXPS = {
        'javascript':   /<script\b[^>]*>([\s\S]*?)<\/script>/g,
        'image':        [/<img\b[^>]*>([\s\S]*?)>{0}/g, /url([\s\S]*?).*;{0}/g],
        'css':          /<link\b[^>]*>([\s\S]*?)>{0}/g,
        'php':          /[include|include_once|require|require_once]([\s\S]*?).*;{0}/g,
        'audio':        /<audio\b[^>]*>([\s\S]*?)<\/audio>/g,
        'video':        /<video\b[^>]*>([\s\S]*?)<\/video>/g
    };

    var VIDEO_EXTENSIONS = ['mp4', 'ogg', 'ogv', 'webm'];

    // Project files storages
    var _watchedFiles = [],
        _watchedFilesCache = [];

    // Watcher function
    var _intervalFunc;

    /**
     * Compares cached project files with current.
     * @private
     * @returns {Array} Full path strings of removed files.
     */
    function _compareFiles() {
        var removedFiles = [];
        _watchedFilesCache.forEach(function (file) {
            if ($.inArray(file, _watchedFiles) === -1) {
                removedFiles.push(file.fullPath);
            }
        });
        return removedFiles;
    }

    /**
     * Removes matched links/tags from text.
     * @private
     * @param   {string} relPath  Relative path.
     * @param   {string} docText  Text of a document to be changed.
     * @param   {string} fileLang Language of the file link to be removed.
     * @returns {string} Text with links/tags removed.
     */
    function _removeLinks(relPath, docText, fileLang) {
        if (fileLang === "unknown" || fileLang === "binary") {
            var fileExt = FileUtils.getFileExtension(relPath);
            if ($.inArray(fileExt, VIDEO_EXTENSIONS) > -1) { fileLang = "video"; }
        }
        if (fileLang === "svg") { fileLang = "image"; }

        var regexp;
        if (fileLang === "image") {
            var editor = EditorManager. getActiveEditor();
            var docLang = editor.getLanguageForSelection().getId();
            if (docLang === "html") {
                regexp = REGEXPS[fileLang][0];
            } else {
                regexp = REGEXPS[fileLang][1];
            }
        } else {
            regexp = REGEXPS[fileLang];
        }

        var links = docText.match(regexp);
        if (links && links.length > 0) {
            links.forEach(function (link) {
                if (link.indexOf(relPath) !== -1) {
                    docText = docText.replace(link, "");
                }
            });
        }
        return docText;
    }

    /**
     * Starts the project files watcher.
     * Sets the scanning every two seconds for removed files and
     * remove links/tags, if any.
     */
    function start() {
        ProjectManager.getAllFiles().done(function (files) {
            _watchedFilesCache = files.slice(0);

            _intervalFunc = setInterval(function () {
                ProjectManager.refreshFileTree();
                ProjectManager.getAllFiles().done(function (files) {
                    _watchedFiles = files.slice(0);
                    var removedFiles = _compareFiles();
                    if (removedFiles.length > 0) {
                        removedFiles.forEach(function (filePath) {
                            var editor = EditorManager. getActiveEditor();
                            if (editor) {
                                var fileLang = LanguageManager.getLanguageForPath(filePath).getId();
                                var relPath = Linker.findRelativePath(filePath, editor.getFile().fullPath);
                                var docText = editor.document.getText();
                                var newText = _removeLinks(relPath, docText, fileLang);
                                editor.document.replaceRange(
                                    newText,
                                    {line: 0, ch: 0},
                                    {line: 9999, ch: 9999}
                                );
                            }
                        });
                    }
                    _watchedFilesCache = files.slice(0);
                });
            }, 2000);

            ProjectManager.on("projectOpen.blfwatcher", function () {
                ProjectManager.getAllFiles().done(function (files) {
                    _watchedFilesCache = files.slice(0);
                });
            });
        });
    }

    /**
     * Stops the project files watcher.
     */
    function stop() {
        clearInterval(_intervalFunc);
        ProjectManager.off("projectOpen.blfwatcher");
    }

    module.exports = {
        start: start,
        stop: stop
    };
});
<|endoftext|>


<commit_before>require('../../../src/leaflet/overlay/GraphicLayer');

var url = "http://supermapiserver:8090/iserver/services/map-world/rest/maps/World";
describe('leaflet_GraphicLayer', function () {
    var originalTimeout;
    var testDiv, map;
    beforeAll(function () {
        testDiv = window.document.createElement("div");
        testDiv.setAttribute("id", "map");
        testDiv.style.styleFloat = "left";
        testDiv.style.marginLeft = "8px";
        testDiv.style.marginTop = "50px";
        testDiv.style.width = "500px";
        testDiv.style.height = "500px";
        window.document.body.appendChild(testDiv);

        map = L.map('map', {
            preferCanvas: true,
            crs: L.CRS.EPSG4326,
            center: {lon: 0, lat: 0},
            maxZoom: 18,
            zoom: 1
        });
        L.supermap.tiledMapLayer(url).addTo(map);
    });
    beforeEach(function () {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
    });
    afterEach(function () {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
    afterAll(function () {
        window.document.body.removeChild(testDiv);
        map.remove();
    });

    it('initialize', function (done) {
        var colorCount = 5, count = 5;
        var graphics = [];
        var e = 45;
        var randomCircleStyles = [];
        for (var i = 0; i < colorCount; i++) {
            randomCircleStyles.push(L.supermap.circleStyle({
                color: '#3388ff',
                opacity: 1,
                radius: 2,
                fill: true,
                fillColor: '#3388ff',
                fillOpacity: 1
            }));
        }
        for (var j = 0; j < count; ++j) {
            var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
            graphics[j] = L.supermap.graphic({
                _latlng: L.latLng(coordinates[0], coordinates[1]),
                _canvas: randomCircleStyles[Math.floor(Math.random() * colorCount)].getCanvas()
            });
        }
        var graphicLayer = L.supermap.graphicLayer(graphics).addTo(map);
        setTimeout(function () {
            expect(graphicLayer.graphics.length).toEqual(count);
            for (var i = 0; i < graphicLayer.graphics.length; i++) {
                expect(graphicLayer.graphics[i]._canvas).not.toBeNull();
                expect(graphicLayer.graphics[i]._latlng).not.toBeNull();
            }
            var isContainsPoint = graphicLayer._containsPoint();
            expect(isContainsPoint).not.toBe("false");
            map.removeLayer(graphicLayer);
            done();
        }, 1000)
    });
});

<commit_msg>fix UT<commit_after>require('../../../src/leaflet/overlay/GraphicLayer');

var url = "http://supermapiserver:8090/iserver/services/map-world/rest/maps/World";
describe('leaflet_GraphicLayer', function () {
    var originalTimeout;
    var testDiv, map;
    beforeAll(function () {
        testDiv = window.document.createElement("div");
        testDiv.setAttribute("id", "map");
        testDiv.style.styleFloat = "left";
        testDiv.style.marginLeft = "8px";
        testDiv.style.marginTop = "50px";
        testDiv.style.width = "500px";
        testDiv.style.height = "500px";
        window.document.body.appendChild(testDiv);

        map = L.map('map', {
            preferCanvas: true,
            crs: L.CRS.EPSG4326,
            center: {lon: 0, lat: 0},
            maxZoom: 18,
            zoom: 1
        });
        L.supermap.tiledMapLayer(url).addTo(map);
    });
    beforeEach(function () {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
    });
    afterEach(function () {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
    afterAll(function () {
        //canvas渲染时由于Path 相关的子类 -> map.remove()会有重绘操作，从而引起刷新延迟会报错，故弃之
        map.off();
        map = null;
        window.document.body.removeChild(testDiv);
    });

    it('initialize', function (done) {
        var colorCount = 5, count = 5;
        var graphics = [];
        var e = 45;
        var randomCircleStyles = [];
        for (var i = 0; i < colorCount; i++) {
            randomCircleStyles.push(L.supermap.circleStyle({
                color: '#3388ff',
                opacity: 1,
                radius: 2,
                fill: true,
                fillColor: '#3388ff',
                fillOpacity: 1
            }));
        }
        for (var j = 0; j < count; ++j) {
            var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
            graphics[j] = L.supermap.graphic({
                _latlng: L.latLng(coordinates[0], coordinates[1]),
                _canvas: randomCircleStyles[Math.floor(Math.random() * colorCount)].getCanvas()
            });
        }
        var graphicLayer = L.supermap.graphicLayer(graphics).addTo(map);

        setTimeout(function () {
            expect(graphicLayer.graphics.length).toEqual(count);
            for (var i = 0; i < graphicLayer.graphics.length; i++) {
                expect(graphicLayer.graphics[i]._canvas).not.toBeNull();
                expect(graphicLayer.graphics[i]._latlng).not.toBeNull();
            }
            var isContainsPoint = graphicLayer._containsPoint();
            expect(isContainsPoint).not.toBe("false");
            graphicLayer.remove();
            done();
        }, 1000)
    });
});

<|endoftext|>


<commit_before>// JavaScript component of watchface to send and recieve messages with Pebble app on the phone.

var xhrRequest = function(url, type, callback){
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){
    callback(this.responseText);
  };
  xhr.open(type, url);
  xhr.send();
};

function locationSuccess(pos){
  // Request for weather
  var url = 'http://api.openweathermap.org/data/2.5/weather?lat=' +
      pos.coords.latitude + '&lon=' + pos.coords.longitude;
  console.log(url);

  // Send a request to OpenWeatherMap.org
  xhrRequest(url, 'GET',
            function(responseText){
              var json = JSON.parse(responseText);

              var temperature = Math.round(json.main.temp - 273.15);
              console.log('The temperature is ' + temperature);

              var conditions = json.weather[0].main;
              console.log('Conditions are ' + conditions);

              var dictionary = {
                'KEY_TEMPERATURE' : temperature,
                'KEY_CONDITIONS' : conditions
              };

              Pebble.sendAppMessage(dictionary,
                                   function(e){
                                     console.log('Weather info sent to Pebble succesfully!');
                                   },
                                   function(e){
                                     console.log('Error sending weather info to Pebble!');
                                   });
            });
}

function locationError(err){
  console.log('Error requesting location!');
}

function getWeather(){
  navigator.geolocation.getCurrentPosition(
  locationSuccess,
  locationError,
    {timeout: 15000, maximumAge: 60000}
  );
}

Pebble.addEventListener('ready',
                        function(e){
                          console.log('PebbleKit JS ready!');

                          // Get the initial weather
                          getWeather();
                        });

Pebble.addEventListener('appmessage',
                       function(e){
                         console.log('AppMessage received!');
                       });

Pebble.addEventListener('appmessage', function(e){
  console.log('AppMessage received!');
  getWeather();
});<commit_msg>Fix weather info<commit_after>// JavaScript component of watchface to send and recieve messages with Pebble app on the phone.

var xhrRequest = function(url, type, callback){
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){
    callback(this.responseText);
  };
  xhr.open(type, url);
  xhr.send();
};

function locationSuccess(pos){
  // Request for weather
  var url = 'http://api.openweathermap.org/data/2.5/weather?lat=' +
      pos.coords.latitude + '&lon=' + pos.coords.longitude +
      '&appid=' + 'f91f86b1ea53eacc3409a80c7ba9d388'; // hardcode appid, anyway it's free
  console.log(url);

  // Send a request to OpenWeatherMap.org
  xhrRequest(url, 'GET',
            function(responseText){
              var json = JSON.parse(responseText);

              var temperature = Math.round(json.main.temp - 273.15);
              console.log('The temperature is ' + temperature);

              var conditions = json.weather[0].main;
              console.log('Conditions are ' + conditions);

              var dictionary = {
                'KEY_TEMPERATURE' : temperature,
                'KEY_CONDITIONS' : conditions
              };

              Pebble.sendAppMessage(dictionary,
                                   function(e){
                                     console.log('Weather info sent to Pebble succesfully!');
                                   },
                                   function(e){
                                     console.log('Error sending weather info to Pebble!');
                                   });
            });
}

function locationError(err){
  console.log('Error requesting location!');
}

function getWeather(){
  navigator.geolocation.getCurrentPosition(
  locationSuccess,
  locationError,
    {timeout: 15000, maximumAge: 60000}
  );
}

Pebble.addEventListener('ready',
                        function(e){
                          console.log('PebbleKit JS ready!');

                          // Get the initial weather
                          getWeather();
                        });

Pebble.addEventListener('appmessage',
                       function(e){
                         console.log('AppMessage received!');
                       });

Pebble.addEventListener('appmessage', function(e){
  console.log('AppMessage received!');
  getWeather();
});<|endoftext|>