/* eslint-disable */

// gif.js 0.2.0 - https://github.com/jnordberg/gif.js
(function (f) {
  if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = f();
  } else if (typeof define === 'function' && define.amd) {
    define([], f);
  } else {
    var g;
    if (typeof window !== 'undefined') {
      g = window;
    } else if (typeof global !== 'undefined') {
      g = global;
    } else if (typeof self !== 'undefined') {
      g = self;
    } else {
      g = this;
    }
    g.GIF = f();
  }
})(function () {
  var define, module, exports;
  return (function e(t, n, r) {
    function s(o, u) {
      if (!n[o]) {
        if (!t[o]) {
          var a = typeof require == 'function' && require;
          if (!u && a) return a(o, !0);
          if (i) return i(o, !0);
          var f = new Error("Cannot find module '" + o + "'");
          throw ((f.code = 'MODULE_NOT_FOUND'), f);
        }
        var l = (n[o] = {
          exports: {},
        });
        t[o][0].call(
          l.exports,
          function (e) {
            var n = t[o][1][e];
            return s(n ? n : e);
          },
          l,
          l.exports,
          e,
          t,
          n,
          r
        );
      }
      return n[o].exports;
    }
    var i = typeof require == 'function' && require;
    for (var o = 0; o < r.length; o++) s(r[o]);
    return s;
  })(
    {
      1: [
        function (require, module, exports) {
          function EventEmitter() {
            this._events = this._events || {};
            this._maxListeners = this._maxListeners || undefined;
          }
          module.exports = EventEmitter;
          EventEmitter.EventEmitter = EventEmitter;
          EventEmitter.prototype._events = undefined;
          EventEmitter.prototype._maxListeners = undefined;
          EventEmitter.defaultMaxListeners = 10;
          EventEmitter.prototype.setMaxListeners = function (n) {
            if (!isNumber(n) || n < 0 || isNaN(n))
              throw TypeError('n must be a positive number');
            this._maxListeners = n;
            return this;
          };
          EventEmitter.prototype.emit = function (type) {
            var er, handler, len, args, i, listeners;
            if (!this._events) this._events = {};
            if (type === 'error') {
              if (
                !this._events.error ||
                (isObject(this._events.error) && !this._events.error.length)
              ) {
                er = arguments[1];
                if (er instanceof Error) {
                  throw er;
                } else {
                  var err = new Error(
                    'Uncaught, unspecified "error" event. (' + er + ')'
                  );
                  err.context = er;
                  throw err;
                }
              }
            }
            handler = this._events[type];
            if (isUndefined(handler)) return false;
            if (isFunction(handler)) {
              switch (arguments.length) {
                case 1:
                  handler.call(this);
                  break;
                case 2:
                  handler.call(this, arguments[1]);
                  break;
                case 3:
                  handler.call(this, arguments[1], arguments[2]);
                  break;
                default:
                  args = Array.prototype.slice.call(arguments, 1);
                  handler.apply(this, args);
              }
            } else if (isObject(handler)) {
              args = Array.prototype.slice.call(arguments, 1);
              listeners = handler.slice();
              len = listeners.length;
              for (i = 0; i < len; i++) listeners[i].apply(this, args);
            }
            return true;
          };
          EventEmitter.prototype.addListener = function (type, listener) {
            var m;
            if (!isFunction(listener))
              throw TypeError('listener must be a function');
            if (!this._events) this._events = {};
            if (this._events.newListener)
              this.emit(
                'newListener',
                type,
                isFunction(listener.listener) ? listener.listener : listener
              );
            if (!this._events[type]) this._events[type] = listener;
            else if (isObject(this._events[type]))
              this._events[type].push(listener);
            else this._events[type] = [this._events[type], listener];
            if (isObject(this._events[type]) && !this._events[type].warned) {
              if (!isUndefined(this._maxListeners)) {
                m = this._maxListeners;
              } else {
                m = EventEmitter.defaultMaxListeners;
              }
              if (m && m > 0 && this._events[type].length > m) {
                this._events[type].warned = true;
                console.error(
                  '(node) warning: possible EventEmitter memory ' +
                    'leak detected. %d listeners added. ' +
                    'Use emitter.setMaxListeners() to increase limit.',
                  this._events[type].length
                );
                if (typeof console.trace === 'function') {
                  console.trace();
                }
              }
            }
            return this;
          };
          EventEmitter.prototype.on = EventEmitter.prototype.addListener;
          EventEmitter.prototype.once = function (type, listener) {
            if (!isFunction(listener))
              throw TypeError('listener must be a function');
            var fired = false;

            function g() {
              this.removeListener(type, g);
              if (!fired) {
                fired = true;
                listener.apply(this, arguments);
              }
            }
            g.listener = listener;
            this.on(type, g);
            return this;
          };
          EventEmitter.prototype.removeListener = function (type, listener) {
            var list, position, length, i;
            if (!isFunction(listener))
              throw TypeError('listener must be a function');
            if (!this._events || !this._events[type]) return this;
            list = this._events[type];
            length = list.length;
            position = -1;
            if (
              list === listener ||
              (isFunction(list.listener) && list.listener === listener)
            ) {
              delete this._events[type];
              if (this._events.removeListener)
                this.emit('removeListener', type, listener);
            } else if (isObject(list)) {
              for (i = length; i-- > 0; ) {
                if (
                  list[i] === listener ||
                  (list[i].listener && list[i].listener === listener)
                ) {
                  position = i;
                  break;
                }
              }
              if (position < 0) return this;
              if (list.length === 1) {
                list.length = 0;
                delete this._events[type];
              } else {
                list.splice(position, 1);
              }
              if (this._events.removeListener)
                this.emit('removeListener', type, listener);
            }
            return this;
          };
          EventEmitter.prototype.removeAllListeners = function (type) {
            var key, listeners;
            if (!this._events) return this;
            if (!this._events.removeListener) {
              if (arguments.length === 0) this._events = {};
              else if (this._events[type]) delete this._events[type];
              return this;
            }
            if (arguments.length === 0) {
              for (key in this._events) {
                if (key === 'removeListener') continue;
                this.removeAllListeners(key);
              }
              this.removeAllListeners('removeListener');
              this._events = {};
              return this;
            }
            listeners = this._events[type];
            if (isFunction(listeners)) {
              this.removeListener(type, listeners);
            } else if (listeners) {
              while (listeners.length)
                this.removeListener(type, listeners[listeners.length - 1]);
            }
            delete this._events[type];
            return this;
          };
          EventEmitter.prototype.listeners = function (type) {
            var ret;
            if (!this._events || !this._events[type]) ret = [];
            else if (isFunction(this._events[type])) ret = [this._events[type]];
            else ret = this._events[type].slice();
            return ret;
          };
          EventEmitter.prototype.listenerCount = function (type) {
            if (this._events) {
              var evlistener = this._events[type];
              if (isFunction(evlistener)) return 1;
              else if (evlistener) return evlistener.length;
            }
            return 0;
          };
          EventEmitter.listenerCount = function (emitter, type) {
            return emitter.listenerCount(type);
          };

          function isFunction(arg) {
            return typeof arg === 'function';
          }

          function isNumber(arg) {
            return typeof arg === 'number';
          }

          function isObject(arg) {
            return typeof arg === 'object' && arg !== null;
          }

          function isUndefined(arg) {
            return arg === void 0;
          }
        },
        {},
      ],
      2: [
        function (require, module, exports) {
          var UA, browser, mode, platform, ua;
          ua = navigator.userAgent.toLowerCase();
          platform = navigator.platform.toLowerCase();
          UA = ua.match(
            /(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/
          ) || [null, 'unknown', 0];
          mode = UA[1] === 'ie' && document.documentMode;
          browser = {
            name: UA[1] === 'version' ? UA[3] : UA[1],
            version:
              mode || parseFloat(UA[1] === 'opera' && UA[4] ? UA[4] : UA[2]),
            platform: {
              name: ua.match(/ip(?:ad|od|hone)/)
                ? 'ios'
                : (ua.match(/(?:webos|android)/) ||
                    platform.match(/mac|win|linux/) || ['other'])[0],
            },
          };
          browser[browser.name] = true;
          browser[browser.name + parseInt(browser.version, 10)] = true;
          browser.platform[browser.platform.name] = true;
          module.exports = browser;
        },
        {},
      ],
      3: [
        function (require, module, exports) {
          var EventEmitter,
            GIF,
            browser,
            extend = function (child, parent) {
              for (var key in parent) {
                if (hasProp.call(parent, key)) child[key] = parent[key];
              }

              function ctor() {
                this.constructor = child;
              }
              ctor.prototype = parent.prototype;
              child.prototype = new ctor();
              child.__super__ = parent.prototype;
              return child;
            },
            hasProp = {}.hasOwnProperty,
            indexOf =
              [].indexOf ||
              function (item) {
                for (var i = 0, l = this.length; i < l; i++) {
                  if (i in this && this[i] === item) return i;
                }
                return -1;
              },
            slice = [].slice;
          EventEmitter = require('events').EventEmitter;
          browser = require('./browser.coffee');
          GIF = (function (superClass) {
            var defaults, frameDefaults;
            extend(GIF, superClass);
            defaults = {
              workerScript: 'gif.worker.js',
              workers: 2,
              repeat: 0,
              background: '#fff',
              quality: 10,
              width: null,
              height: null,
              transparent: null,
              debug: false,
              dither: false,
            };
            frameDefaults = {
              delay: 500,
              copy: false,
            };

            function GIF(options) {
              var base, key, value;
              this.running = false;
              this.options = {};
              this.frames = [];
              this.freeWorkers = [];
              this.activeWorkers = [];
              this.setOptions(options);
              for (key in defaults) {
                value = defaults[key];
                if ((base = this.options)[key] == null) {
                  base[key] = value;
                }
              }
            }
            GIF.prototype.setOption = function (key, value) {
              this.options[key] = value;
              if (
                this._canvas != null &&
                (key === 'width' || key === 'height')
              ) {
                return (this._canvas[key] = value);
              }
            };
            GIF.prototype.setOptions = function (options) {
              var key, results, value;
              results = [];
              for (key in options) {
                if (!hasProp.call(options, key)) continue;
                value = options[key];
                results.push(this.setOption(key, value));
              }
              return results;
            };
            GIF.prototype.addFrame = function (image, options) {
              var frame, key;
              if (options == null) {
                options = {};
              }
              frame = {};
              frame.transparent = this.options.transparent;
              for (key in frameDefaults) {
                frame[key] = options[key] || frameDefaults[key];
              }
              if (this.options.width == null) {
                this.setOption('width', image.width);
              }
              if (this.options.height == null) {
                this.setOption('height', image.height);
              }
              if (
                typeof ImageData !== 'undefined' &&
                ImageData !== null &&
                image instanceof ImageData
              ) {
                frame.data = image.data;
              } else if (
                (typeof CanvasRenderingContext2D !== 'undefined' &&
                  CanvasRenderingContext2D !== null &&
                  image instanceof CanvasRenderingContext2D) ||
                (typeof WebGLRenderingContext !== 'undefined' &&
                  WebGLRenderingContext !== null &&
                  image instanceof WebGLRenderingContext)
              ) {
                if (options.copy) {
                  frame.data = this.getContextData(image);
                } else {
                  frame.context = image;
                }
              } else if (image.childNodes != null) {
                if (options.copy) {
                  frame.data = this.getImageData(image);
                } else {
                  frame.image = image;
                }
              } else {
                throw new Error('Invalid image');
              }
              return this.frames.push(frame);
            };
            GIF.prototype.render = function () {
              var i, j, numWorkers, ref;
              if (this.running) {
                throw new Error('Already running');
              }
              if (this.options.width == null || this.options.height == null) {
                throw new Error(
                  'Width and height must be set prior to rendering'
                );
              }
              this.running = true;
              this.nextFrame = 0;
              this.finishedFrames = 0;
              this.imageParts = function () {
                var j, ref, results;
                results = [];
                for (
                  i = j = 0, ref = this.frames.length;
                  0 <= ref ? j < ref : j > ref;
                  i = 0 <= ref ? ++j : --j
                ) {
                  results.push(null);
                }
                return results;
              }.call(this);
              numWorkers = this.spawnWorkers();
              if (this.options.globalPalette === true) {
                this.renderNextFrame();
              } else {
                for (
                  i = j = 0, ref = numWorkers;
                  0 <= ref ? j < ref : j > ref;
                  i = 0 <= ref ? ++j : --j
                ) {
                  this.renderNextFrame();
                }
              }
              this.emit('start');
              return this.emit('progress', 0);
            };
            GIF.prototype.abort = function () {
              var worker;
              while (true) {
                worker = this.activeWorkers.shift();
                if (worker == null) {
                  break;
                }
                this.log('killing active worker');
                worker.terminate();
              }
              this.running = false;
              return this.emit('abort');
            };
            GIF.prototype.spawnWorkers = function () {
              var j, numWorkers, ref, results;
              numWorkers = Math.min(this.options.workers, this.frames.length);
              (function () {
                results = [];
                for (
                  var j = (ref = this.freeWorkers.length);
                  ref <= numWorkers ? j < numWorkers : j > numWorkers;
                  ref <= numWorkers ? j++ : j--
                ) {
                  results.push(j);
                }
                return results;
              }
                .apply(this)
                .forEach(
                  (function (_this) {
                    return function (i) {
                      var worker;
                      _this.log('spawning worker ' + i);
                      worker = new Worker(_this.options.workerScript);
                      worker.onmessage = function (event) {
                        _this.activeWorkers.splice(
                          _this.activeWorkers.indexOf(worker),
                          1
                        );
                        _this.freeWorkers.push(worker);
                        return _this.frameFinished(event.data);
                      };
                      return _this.freeWorkers.push(worker);
                    };
                  })(this)
                ));
              return numWorkers;
            };
            GIF.prototype.frameFinished = function (frame) {
              var i, j, ref;
              this.log(
                'frame ' +
                  frame.index +
                  ' finished - ' +
                  this.activeWorkers.length +
                  ' active'
              );
              this.finishedFrames++;
              this.emit('progress', this.finishedFrames / this.frames.length);
              this.imageParts[frame.index] = frame;
              if (this.options.globalPalette === true) {
                this.options.globalPalette = frame.globalPalette;
                this.log('global palette analyzed');
                if (this.frames.length > 2) {
                  for (
                    i = j = 1, ref = this.freeWorkers.length;
                    1 <= ref ? j < ref : j > ref;
                    i = 1 <= ref ? ++j : --j
                  ) {
                    this.renderNextFrame();
                  }
                }
              }
              if (indexOf.call(this.imageParts, null) >= 0) {
                return this.renderNextFrame();
              } else {
                return this.finishRendering();
              }
            };
            GIF.prototype.finishRendering = function () {
              var data,
                frame,
                i,
                image,
                j,
                k,
                l,
                len,
                len1,
                len2,
                len3,
                offset,
                page,
                ref,
                ref1,
                ref2;
              len = 0;
              ref = this.imageParts;
              for (j = 0, len1 = ref.length; j < len1; j++) {
                frame = ref[j];
                len += (frame.data.length - 1) * frame.pageSize + frame.cursor;
              }
              len += frame.pageSize - frame.cursor;
              this.log(
                'rendering finished - filesize ' + Math.round(len / 1e3) + 'kb'
              );
              data = new Uint8Array(len);
              offset = 0;
              ref1 = this.imageParts;
              for (k = 0, len2 = ref1.length; k < len2; k++) {
                frame = ref1[k];
                ref2 = frame.data;
                for (i = l = 0, len3 = ref2.length; l < len3; i = ++l) {
                  page = ref2[i];
                  data.set(page, offset);
                  if (i === frame.data.length - 1) {
                    offset += frame.cursor;
                  } else {
                    offset += frame.pageSize;
                  }
                }
              }
              image = new Blob([data], {
                type: 'image/gif',
              });
              return this.emit('finished', image, data);
            };
            GIF.prototype.renderNextFrame = function () {
              var frame, task, worker;
              if (this.freeWorkers.length === 0) {
                throw new Error('No free workers');
              }
              if (this.nextFrame >= this.frames.length) {
                return;
              }
              frame = this.frames[this.nextFrame++];
              worker = this.freeWorkers.shift();
              task = this.getTask(frame);
              this.log(
                'starting frame ' +
                  (task.index + 1) +
                  ' of ' +
                  this.frames.length
              );
              this.activeWorkers.push(worker);
              return worker.postMessage(task);
            };
            GIF.prototype.getContextData = function (ctx) {
              return ctx.getImageData(
                0,
                0,
                this.options.width,
                this.options.height
              ).data;
            };
            GIF.prototype.getImageData = function (image) {
              var ctx;
              if (this._canvas == null) {
                this._canvas = document.createElement('canvas');
                this._canvas.width = this.options.width;
                this._canvas.height = this.options.height;
              }
              ctx = this._canvas.getContext('2d');
              ctx.fillStyle = this.options.background;
              ctx.fillRect(0, 0, this.options.width, this.options.height);
              ctx.drawImage(image, 0, 0);
              return this.getContextData(ctx);
            };
            GIF.prototype.getTask = function (frame) {
              var index, task;
              index = this.frames.indexOf(frame);
              task = {
                index: index,
                last: index === this.frames.length - 1,
                delay: frame.delay,
                transparent: frame.transparent,
                width: this.options.width,
                height: this.options.height,
                quality: this.options.quality,
                dither: this.options.dither,
                globalPalette: this.options.globalPalette,
                repeat: this.options.repeat,
                canTransfer: browser.name === 'chrome',
              };
              if (frame.data != null) {
                task.data = frame.data;
              } else if (frame.context != null) {
                task.data = this.getContextData(frame.context);
              } else if (frame.image != null) {
                task.data = this.getImageData(frame.image);
              } else {
                throw new Error('Invalid frame');
              }
              return task;
            };
            GIF.prototype.log = function () {
              var args;
              args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
              if (!this.options.debug) {
                return;
              }
              return console.log.apply(console, args);
            };
            return GIF;
          })(EventEmitter);
          module.exports = GIF;
        },
        {
          './browser.coffee': 2,
          events: 1,
        },
      ],
    },
    {},
    [3]
  )(3);
});
//# sourceMappingURL=gif.js.map
