(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports);
    global.potpackModule = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.potpack = potpack;

  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

  /**
   * potpack - by [@mourner](https://github.com/mourner)
   * 
   * A tiny JavaScript function for packing 2D rectangles into a near-square container, 
   * which is useful for generating CSS sprites and WebGL textures. Similar to 
   * [shelf-pack](https://github.com/mapbox/shelf-pack), but static (you can't add items 
   * once a layout is generated), and aims for maximal space utilization.
   *
   * A variation of algorithms used in [rectpack2D](https://github.com/TeamHypersomnia/rectpack2D)
   * and [bin-pack](https://github.com/bryanburgers/bin-pack), which are in turn based 
   * on [this article by Blackpawn](http://blackpawn.com/texts/lightmaps/default.html).
   * 
   * @license
   * ISC License
   * 
   * Copyright (c) 2018, Mapbox
   * 
   * Permission to use, copy, modify, and/or distribute this software for any purpose
   * with or without fee is hereby granted, provided that the above copyright notice
   * and this permission notice appear in all copies.
   * 
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
   * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
   * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
   * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
   * THIS SOFTWARE.
   */
  function potpack(boxes) {
    // calculate total box area and maximum box width
    var area = 0;
    var maxWidth = 0;

    var _iterator = _createForOfIteratorHelper(boxes),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var box = _step.value;
        area += box.w * box.h;
        maxWidth = Math.max(maxWidth, box.w);
      } // sort the boxes for insertion by height, descending

    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }

    boxes.sort(function (a, b) {
      return b.h - a.h;
    }); // aim for a squarish resulting container,
    // slightly adjusted for sub-100% space utilization

    var startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth); // start with a single empty space, unbounded at the bottom

    var spaces = [{
      x: 0,
      y: 0,
      w: startWidth,
      h: Infinity
    }];
    var width = 0;
    var height = 0;

    var _iterator2 = _createForOfIteratorHelper(boxes),
        _step2;

    try {
      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
        var _box = _step2.value;

        // look through spaces backwards so that we check smaller spaces first
        for (var i = spaces.length - 1; i >= 0; i--) {
          var space = spaces[i]; // look for empty spaces that can accommodate the current box

          if (_box.w > space.w || _box.h > space.h) continue; // found the space; add the box to its top-left corner
          // |-------|-------|
          // |  box  |       |
          // |_______|       |
          // |         space |
          // |_______________|

          _box.x = space.x;
          _box.y = space.y;
          height = Math.max(height, _box.y + _box.h);
          width = Math.max(width, _box.x + _box.w);

          if (_box.w === space.w && _box.h === space.h) {
            // space matches the box exactly; remove it
            var last = spaces.pop();
            if (i < spaces.length) spaces[i] = last;
          } else if (_box.h === space.h) {
            // space matches the box height; update it accordingly
            // |-------|---------------|
            // |  box  | updated space |
            // |_______|_______________|
            space.x += _box.w;
            space.w -= _box.w;
          } else if (_box.w === space.w) {
            // space matches the box width; update it accordingly
            // |---------------|
            // |      box      |
            // |_______________|
            // | updated space |
            // |_______________|
            space.y += _box.h;
            space.h -= _box.h;
          } else {
            // otherwise the box splits the space into two spaces
            // |-------|-----------|
            // |  box  | new space |
            // |_______|___________|
            // | updated space     |
            // |___________________|
            spaces.push({
              x: space.x + _box.w,
              y: space.y,
              w: space.w - _box.w,
              h: _box.h
            });
            space.y += _box.h;
            space.h -= _box.h;
          }

          break;
        }
      }
    } catch (err) {
      _iterator2.e(err);
    } finally {
      _iterator2.f();
    }

    return {
      w: width,
      // container width
      h: height,
      // container height
      fill: area / (width * height) || 0 // space utilization

    };
  }
});