text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.createConcat = void 0;
  
  var _is = require("../../utils/is");
  
  var _object = require("../../utils/object");
  
  var _array = require("../../utils/array");
  
  var _IndexError = require("../../error/IndexError");
  
  var _DimensionError = require("../../error/DimensionError");
  
  var _factory = require("../../utils/factory");
  
  var name = 'concat';
  var dependencies = ['typed', 'matrix', 'isInteger'];
  var createConcat =
  /* #__PURE__ */
  (0, _factory.factory)(name, dependencies, function (_ref) {
    var typed = _ref.typed,
        matrix = _ref.matrix,
        isInteger = _ref.isInteger;
  
    /**
     * Concatenate two or more matrices.
     *
     * Syntax:
     *
     *     math.concat(A, B, C, ...)
     *     math.concat(A, B, C, ..., dim)
     *
     * Where:
     *
     * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
     *   By default the last dimension of the matrices.
     *
     * Examples:
     *
     *    const A = [[1, 2], [5, 6]]
     *    const B = [[3, 4], [7, 8]]
     *
     *    math.concat(A, B)                  // returns [[1, 2, 3, 4], [5, 6, 7, 8]]
     *    math.concat(A, B, 0)               // returns [[1, 2], [5, 6], [3, 4], [7, 8]]
     *    math.concat('hello', ' ', 'world') // returns 'hello world'
     *
     * See also:
     *
     *    size, squeeze, subset, transpose
     *
     * @param {... Array | Matrix} args     Two or more matrices
     * @return {Array | Matrix} Concatenated matrix
     */
    return typed(name, {
      // TODO: change signature to '...Array | Matrix, dim?' when supported
      '...Array | Matrix | number | BigNumber': function ArrayMatrixNumberBigNumber(args) {
        var i;
        var len = args.length;
        var dim = -1; // zero-based dimension
  
        var prevDim;
        var asMatrix = false;
        var matrices = []; // contains multi dimensional arrays
  
        for (i = 0; i < len; i++) {
          var arg = args[i]; // test whether we need to return a Matrix (if not we return an Array)
  
          if ((0, _is.isMatrix)(arg)) {
            asMatrix = true;
          }
  
          if ((0, _is.isNumber)(arg) || (0, _is.isBigNumber)(arg)) {
            if (i !== len - 1) {
              throw new Error('Dimension must be specified as last argument');
            } // last argument contains the dimension on which to concatenate
  
  
            prevDim = dim;
            dim = arg.valueOf(); // change BigNumber to number
  
            if (!isInteger(dim)) {
              throw new TypeError('Integer number expected for dimension');
            }
  
            if (dim < 0 || i > 0 && dim > prevDim) {
              // TODO: would be more clear when throwing a DimensionError here
              throw new _IndexError.IndexError(dim, prevDim + 1);
            }
          } else {
            // this is a matrix or array
            var m = (0, _object.clone)(arg).valueOf();
            var size = (0, _array.arraySize)(m);
            matrices[i] = m;
            prevDim = dim;
            dim = size.length - 1; // verify whether each of the matrices has the same number of dimensions
  
            if (i > 0 && dim !== prevDim) {
              throw new _DimensionError.DimensionError(prevDim + 1, dim + 1);
            }
          }
        }
  
        if (matrices.length === 0) {
          throw new SyntaxError('At least one matrix expected');
        }
  
        var res = matrices.shift();
  
        while (matrices.length) {
          res = _concat(res, matrices.shift(), dim, 0);
        }
  
        return asMatrix ? matrix(res) : res;
      },
      '...string': function string(args) {
        return args.join('');
      }
    });
  });
  /**
   * Recursively concatenate two matrices.
   * The contents of the matrices is not cloned.
   * @param {Array} a             Multi dimensional array
   * @param {Array} b             Multi dimensional array
   * @param {number} concatDim    The dimension on which to concatenate (zero-based)
   * @param {number} dim          The current dim (zero-based)
   * @return {Array} c            The concatenated matrix
   * @private
   */
  
  exports.createConcat = createConcat;
  
  function _concat(a, b, concatDim, dim) {
    if (dim < concatDim) {
      // recurse into next dimension
      if (a.length !== b.length) {
        throw new _DimensionError.DimensionError(a.length, b.length);
      }
  
      var c = [];
  
      for (var i = 0; i < a.length; i++) {
        c[i] = _concat(a[i], b[i], concatDim, dim + 1);
      }
  
      return c;
    } else {
      // concatenate this dimension
      return a.concat(b);
    }
  }