import { AcDbFace as E, AcDbArc as M, AcGeVector3d as D, AcDbCircle as L, AcDbEllipse as C, AcDbLine as x, AcGePoint3d as I, AcDbSpline as w, AcDbPoint as v, AcDbTrace as O, AcDbPolyline as k, AcGePoint2d as y, AcDbPoly2dType as A, AcDb2dPolyline as R, AcDbPoly3dType as b, AcDb3dPolyline as m, AcDbHatch as V, AcGePolyline2d as N, AcGeLoop2d as F, AcGeLine2d as B, AcGeCircArc2d as j, AcGeVector2d as z, AcGeEllipseArc2d as W, AcGeSpline3d as T, AcDbTable as H, AcDbText as X, AcDbMText as G, AcDbLeader as U, AcDbAlignedDimension as Y, AcDb3PointAngularDimension as Z, AcDbOrdinateDimension as _, AcDbRadialDimension as K, AcDbDiametricDimension as q, AcDbRasterImage as J, AcDbWipeout as Q, AcDbViewport as $, AcDbRay as ee, AcDbXline as ne, AcDbBlockReference as te, AcCmTransparency as oe, AcDbDatabaseConverter as se, createWorkerApi as re, AcDbLinetypeTableRecord as ie, AcDbTextStyleTableRecord as ce, AcDbDimStyleTableRecord as ae, AcCmColor as le, AcDbLayerTableRecord as de, AcDbViewportTableRecord as pe, AcDbBlockTableRecord as ue, AcDbBatchProcessing as fe, AcDbLayout as he, AcDbRasterImageDef as De } from "@mlightcad/data-model";
class P {
  convert(e) {
    const n = this.createEntity(e);
    return n && this.processCommonAttrs(e, n), n;
  }
  /**
   * Create the corresponding drawing database entity from data in dxf format
   * @param entity Input entity data in dxf format
   * @returns Return the converted drawing database entity
   */
  createEntity(e) {
    return e.type == "3DFACE" ? this.convertFace(e) : e.type == "ARC" ? this.convertArc(e) : e.type == "CIRCLE" ? this.convertCirle(e) : e.type == "DIMENSION" ? this.convertDimension(e) : e.type == "ELLIPSE" ? this.convertEllipse(e) : e.type == "HATCH" ? this.convertHatch(e) : e.type == "IMAGE" ? this.convertImage(e) : e.type == "LEADER" ? this.convertLeader(e) : e.type == "LINE" ? this.convertLine(e) : e.type == "LWPOLYLINE" ? this.convertLWPolyline(e) : e.type == "MTEXT" ? this.convertMText(e) : e.type == "POINT" ? this.convertPoint(e) : e.type == "POLYLINE2D" ? this.convertPolyline2d(e) : e.type == "POLYLINE3D" ? this.convertPolyline3d(e) : e.type == "RAY" ? this.convertRay(e) : e.type == "SPLINE" ? this.convertSpline(e) : e.type == "ACAD_TABLE" ? this.convertTable(e) : e.type == "TEXT" ? this.convertText(e) : e.type == "SOLID" ? this.convertSolid(e) : e.type == "VIEWPORT" ? this.convertViewport(e) : e.type == "WIPEOUT" ? this.convertWipeout(e) : e.type == "XLINE" ? this.convertXline(e) : e.type == "INSERT" ? this.convertBlockReference(e) : null;
  }
  convertFace(e) {
    const n = new E();
    return e.corner1 && n.setVertexAt(0, e.corner1), e.corner2 && n.setVertexAt(1, e.corner2), e.corner3 && n.setVertexAt(2, e.corner3), e.corner4 && n.setVertexAt(3, e.corner4), n.setEdgeInvisibilities(e.flag), n;
  }
  convertArc(e) {
    return new M(
      e.center,
      e.radius,
      e.startAngle,
      e.endAngle,
      e.extrusionDirection ?? D.Z_AXIS
    );
  }
  convertCirle(e) {
    return new L(
      e.center,
      e.radius,
      e.extrusionDirection ?? D.Z_AXIS
    );
  }
  convertEllipse(e) {
    const n = new D(e.majorAxisEndPoint), s = n.length();
    return new C(
      e.center,
      e.extrusionDirection ?? D.Z_AXIS,
      n,
      s,
      s * e.axisRatio,
      e.startAngle,
      e.endAngle
    );
  }
  convertLine(e) {
    const n = e.startPoint, s = e.endPoint;
    return new x(
      new I(n.x, n.y, n.z),
      new I(s.x, s.y, s.z)
    );
  }
  convertSpline(e) {
    try {
      if (e.numberOfControlPoints > 0 && e.numberOfKnots > 0)
        return new w(
          e.controlPoints,
          e.knots,
          e.weights,
          e.degree,
          !!(e.flag & 1)
        );
      if (e.numberOfFitPoints > 0)
        return new w(
          e.fitPoints,
          "Uniform",
          e.degree,
          !!(e.flag & 1)
        );
    } catch (n) {
      console.log(`Failed to convert spline with error: ${n}`);
    }
    return null;
  }
  convertPoint(e) {
    const n = new v();
    return n.position = e.position, n;
  }
  convertSolid(e) {
    const n = new O();
    return n.setPointAt(0, { ...e.corner1, z: 0 }), n.setPointAt(1, { ...e.corner2, z: 0 }), n.setPointAt(2, { ...e.corner3, z: 0 }), n.setPointAt(
      3,
      e.corner4 ? { ...e.corner4, z: 0 } : { ...e.corner3, z: 0 }
    ), n.thickness = e.thickness, n;
  }
  convertLWPolyline(e) {
    const n = new k();
    return n.closed = !!(e.flag & 512), e.vertices.forEach((s, t) => {
      n.addVertexAt(
        t,
        new y(s.x, s.y),
        s.bulge,
        s.startWidth,
        s.endWidth
      );
    }), n;
  }
  convertPolyline2d(e) {
    const n = !!(e.flag & 1), s = [], t = [];
    e.vertices.map((r) => {
      r.flag & 16 || (s.push({
        x: r.x,
        y: r.y,
        z: r.z
      }), t.push(r.bulge ?? 0));
    });
    let o = A.SimplePoly;
    return e.flag & 2 ? o = A.FitCurvePoly : e.flag & 4 && (e.smoothType == 6 ? o = A.CubicSplinePoly : e.smoothType == 5 && (o = A.QuadSplinePoly)), new R(
      o,
      s,
      0,
      n,
      e.startWidth,
      e.endWidth,
      t
    );
  }
  convertPolyline3d(e) {
    const n = !!(e.flag & 1), s = [];
    e.vertices.map((o) => {
      o.flag & 16 || s.push({
        x: o.x,
        y: o.y,
        z: o.z
      });
    });
    let t = b.SimplePoly;
    return e.flag & 4 && (e.smoothType == 6 ? t = b.CubicSplinePoly : e.smoothType == 5 && (t = b.QuadSplinePoly)), new m(t, s, n);
  }
  convertHatch(e) {
    var t;
    const n = new V();
    return (t = e.definitionLines) == null || t.forEach((o) => {
      n.definitionLines.push({
        angle: o.angle,
        origin: o.base,
        delta: o.offset,
        dashPattern: o.numberOfDashLengths > 0 ? o.dashLengths : []
      });
    }), n.isSolidFill = e.solidFill == 1, n.hatchStyle = e.hatchStyle, n.patternName = e.patternName, n.patternType = e.patternType, n.patternAngle = e.patternAngle == null ? 0 : e.patternAngle, n.patternScale = e.patternScale == null ? 0 : e.patternScale, e.boundaryPaths.forEach((o) => {
      if (o.boundaryPathTypeFlag & 2) {
        const a = o, i = new N();
        i.closed = a.isClosed, a.vertices.forEach((l, c) => {
          i.addVertexAt(c, {
            x: l.x,
            y: l.y,
            bulge: l.bulge
          });
        }), n.add(i);
      } else {
        const a = o, i = new F();
        a.edges.forEach((l) => {
          if (l != null) {
            if (l.type == 1) {
              const c = l;
              i.add(new B(c.start, c.end));
            } else if (l.type == 2) {
              const c = l;
              i.add(
                new j(
                  c.center,
                  c.radius,
                  c.startAngle,
                  c.endAngle,
                  !c.isCCW
                )
              );
            } else if (l.type == 3) {
              const c = l;
              new z().subVectors(c.end, c.center);
              const p = Math.sqrt(
                Math.pow(c.end.x, 2) + Math.pow(c.end.y, 2)
              ), f = p * c.lengthOfMinorAxis;
              let d = c.startAngle, h = c.endAngle;
              const g = Math.atan2(c.end.y, c.end.x);
              c.isCCW || (d = Math.PI * 2 - d, h = Math.PI * 2 - h), i.add(
                new W(
                  { ...c.center, z: 0 },
                  p,
                  f,
                  d,
                  h,
                  !c.isCCW,
                  g
                )
              );
            } else if (l.type == 4) {
              const c = l;
              if (c.numberOfControlPoints > 0 && c.numberOfKnots > 0) {
                const u = c.controlPoints.map(
                  (d) => ({
                    x: d.x,
                    y: d.y,
                    z: 0
                  })
                );
                let p = !0;
                const f = c.controlPoints.map((d) => (d.weight == null && (p = !1), d.weight || 1));
                i.add(
                  new T(
                    u,
                    c.knots,
                    p ? f : void 0
                  )
                );
              } else if (c.numberOfFitData > 0) {
                const u = c.fitDatum.map((p) => ({
                  x: p.x,
                  y: p.y,
                  z: 0
                }));
                i.add(new T(u, "Uniform"));
              }
            }
          }
        }), n.add(i);
      }
    }), n;
  }
  convertTable(e) {
    const n = new H(
      e.name,
      e.rowCount,
      e.columnCount
    );
    return n.attachmentPoint = e.attachmentPoint, n.position.copy(e.startPoint), e.columnWidthArr.forEach(
      (s, t) => n.setColumnWidth(t, s)
    ), e.rowHeightArr.forEach(
      (s, t) => n.setRowHeight(t, s)
    ), e.cells.forEach((s, t) => {
      n.setCell(t, s);
    }), n;
  }
  convertText(e) {
    const n = new X();
    return n.textString = e.text, n.styleName = e.styleName, n.height = e.textHeight, n.position.copy(e.startPoint), n.rotation = e.rotation, n.oblique = e.obliqueAngle ?? 0, n.thickness = e.thickness, n.horizontalMode = e.halign, n.verticalMode = e.valign, n.widthFactor = e.xScale ?? 1, n;
  }
  convertMText(e) {
    const n = new G();
    return n.contents = e.text, e.styleName != null && (n.styleName = e.styleName), n.height = e.textHeight, n.width = e.rectWidth, n.rotation = e.rotation || 0, n.location = e.insertionPoint, n.attachmentPoint = e.attachmentPoint, e.direction && (n.direction = new D(e.direction)), n.drawingDirection = e.drawingDirection, n;
  }
  convertLeader(e) {
    const n = new U();
    return e.vertices.forEach((s) => {
      n.appendVertex(s);
    }), n.hasArrowHead = e.isArrowheadEnabled, n.hasHookLine = e.isHooklineExists, n.isSplined = e.isSpline, n.dimensionStyle = e.styleName, n.annoType = e.leaderCreationFlag, n;
  }
  convertDimension(e) {
    if (e.subclassMarker == "AcDbAlignedDimension" || e.subclassMarker == "AcDbRotatedDimension") {
      const n = e, s = new Y(
        n.subDefinitionPoint1,
        n.subDefinitionPoint2,
        n.definitionPoint
      );
      return n.insertionPoint && (s.dimBlockPosition = {
        x: n.insertionPoint.x,
        y: n.insertionPoint.y,
        z: 0
      }), s.rotation = n.rotationAngle, this.processDimensionCommonAttrs(e, s), s;
    } else if (e.subclassMarker == "AcDb3PointAngularDimension") {
      const n = e, s = new Z(
        n.centerPoint,
        n.subDefinitionPoint1,
        n.subDefinitionPoint2,
        n.definitionPoint
      );
      return this.processDimensionCommonAttrs(e, s), s;
    } else if (e.subclassMarker == "AcDbOrdinateDimension") {
      const n = e, s = new _(
        n.subDefinitionPoint1,
        n.subDefinitionPoint2
      );
      return this.processDimensionCommonAttrs(e, s), s;
    } else if (e.subclassMarker == "AcDbRadialDimension") {
      const n = e, s = new K(
        n.definitionPoint,
        n.centerPoint,
        n.leaderLength
      );
      return this.processDimensionCommonAttrs(e, s), s;
    } else if (e.subclassMarker == "AcDbDiametricDimension") {
      const n = e, s = new q(
        n.definitionPoint,
        n.centerPoint,
        n.leaderLength
      );
      return this.processDimensionCommonAttrs(e, s), s;
    }
    return null;
  }
  processImage(e, n) {
    n.position.copy(e.position), n.brightness = e.brightness, n.contrast = e.contrast, n.fade = e.fade, n.imageDefId = e.imageDefHandle.toString(), n.isClipped = e.clipping > 0, n.isShownClipped = (e.flags | 4) > 0, n.isImageShown = (e.flags | 3) > 0, n.isImageTransparent = (e.flags | 8) > 0, e.clippingBoundaryPath.forEach((s) => {
      n.clipBoundary.push(new y(s));
    }), n.clipBoundaryType = e.clippingBoundaryType, n.width = Math.sqrt(
      e.uPixel.x ** 2 + e.uPixel.y ** 2 + e.uPixel.z ** 2
    ) * e.imageSize.x, n.height = Math.sqrt(
      e.vPixel.x ** 2 + e.vPixel.y ** 2 + e.vPixel.z ** 2
    ) * e.imageSize.y, n.rotation = Math.atan2(e.uPixel.y, e.uPixel.x);
  }
  convertImage(e) {
    const n = new J();
    return this.processImage(e, n), n;
  }
  convertWipeout(e) {
    const n = new Q();
    return this.processImage(e, n), n;
  }
  convertViewport(e) {
    const n = new $();
    return n.number = e.viewportId, n.centerPoint.copy(e.viewportCenter), n.height = e.height, n.width = e.width, n.viewCenter.copy(e.displayCenter), n.viewHeight = e.viewHeight, n;
  }
  convertRay(e) {
    const n = new ee();
    return n.basePoint.copy(e.firstPoint), n.unitDir.copy(e.unitDirection), n;
  }
  convertXline(e) {
    const n = new ne();
    return n.basePoint.copy(e.firstPoint), n.unitDir.copy(e.unitDirection), n;
  }
  convertBlockReference(e) {
    const n = new te(e.name);
    return e.insertionPoint && n.position.copy(e.insertionPoint), n.scaleFactors.x = e.xScale, n.scaleFactors.y = e.yScale, n.scaleFactors.z = e.zScale, n.rotation = e.rotation, n.normal.copy(e.extrusionDirection), n;
  }
  processDimensionCommonAttrs(e, n) {
    n.dimBlockId = e.name, n.textPosition.copy(e.textPoint), n.textRotation = e.textRotation || 0, e.textLineSpacingFactor && (n.textLineSpacingFactor = e.textLineSpacingFactor), e.textLineSpacingStyle && (n.textLineSpacingStyle = e.textLineSpacingStyle), n.dimensionStyleName = e.styleName, n.dimensionText = e.text || "", n.measurement = e.measurement;
  }
  processCommonAttrs(e, n) {
    if (n.layer = e.layer || "0", n.objectId = e.handle.toString(), n.ownerId = e.ownerBlockRecordSoftId.toString(), e.lineType != null && (n.lineType = e.lineType), e.lineweight != null && (n.lineWeight = e.lineweight), e.lineTypeScale != null && (n.linetypeScale = e.lineTypeScale), e.color != null && n.color.setRGBValue(e.color), e.colorIndex != null && (n.color.colorIndex = e.colorIndex), e.colorName && (n.color.colorName = e.colorName), e.isVisible != null && (n.visibility = e.isVisible), e.transparency != null) {
      const s = new oe();
      s.method = e.transparencyType, (s.isByBlock || s.isByBlock) && (s.alpha = e.transparency), n.transparency = s;
    }
  }
}
class Ae extends se {
  constructor(e = {}) {
    super(e), e.useWorker = !0, e.parserWorkerUrl || (e.parserWorkerUrl = "/assets/libredwg-parser-worker.js");
  }
  async parse(e) {
    if (this.config.useWorker && this.config.parserWorkerUrl) {
      const n = re({
        workerUrl: this.config.parserWorkerUrl,
        // One concurrent worker needed for parser
        maxConcurrentWorkers: 1
      }), s = await n.execute(e);
      return n.destroy(), s.data;
    } else
      throw new Error("dwg converter can run in web worker only!");
  }
  /**
   * Gets all of fonts used by entities in model space and paper space
   * @param dwg dwg database model
   * @returns Returns all of fonts used by entities in model space and paper space
   */
  getFonts(e) {
    const n = /* @__PURE__ */ new Map();
    e.tables.BLOCK_RECORD.entries.forEach((r) => {
      n.set(r.name, r);
    });
    const s = /* @__PURE__ */ new Map(), t = (r) => {
      if (r) {
        const a = r.lastIndexOf(".");
        return a >= 0 ? r.substring(0, a).toLowerCase() : r.toLowerCase();
      }
    };
    e.tables.STYLE.entries.forEach((r) => {
      const a = [];
      let i = t(r.font);
      i && a.push(i), i = t(r.bigFont), i && a.push(i), s.set(r.name, a);
    });
    const o = /* @__PURE__ */ new Set();
    return this.getFontsInBlock(e.entities, n, s, o), Array.from(o);
  }
  /**
   * Iterate entities in model space to get fonts used by text, mtext and insert entities
   */
  getFontsInBlock(e, n, s, t) {
    const o = /\\f(.*?)\|/g;
    e.forEach((r) => {
      if (r.type == "MTEXT") {
        const a = r;
        [...a.text.matchAll(o)].forEach((l) => {
          t.add(l[1].toLowerCase());
        });
        const i = s.get(a.styleName);
        i == null || i.forEach((l) => t.add(l));
      } else if (r.type == "TEXT") {
        const a = r, i = s.get(a.styleName);
        i == null || i.forEach((l) => t.add(l));
      } else if (r.type == "INSERT") {
        const a = r, i = n.get(a.name);
        i && this.getFontsInBlock(i.entities, n, s, t);
      }
    });
  }
  processLineTypes(e, n) {
    e.tables.LTYPE.entries.forEach((t) => {
      const o = {
        name: t.name,
        description: t.description,
        standardFlag: t.standardFlag,
        totalPatternLength: t.totalPatternLength,
        pattern: t.pattern
      }, r = new ie(o);
      this.processCommonTableEntryAttrs(t, r), r.name = t.name, n.tables.linetypeTable.add(r);
    });
  }
  processTextStyles(e, n) {
    e.tables.STYLE.entries.forEach((t) => {
      const o = new ce(t);
      this.processCommonTableEntryAttrs(t, o), n.tables.textStyleTable.add(o);
    });
  }
  processDimStyles(e, n) {
    e.tables.DIMSTYLE.entries.forEach((t) => {
      const o = {
        name: t.name,
        ownerId: t.ownerHandle.toString(),
        dimpost: t.DIMPOST || "",
        dimapost: t.DIMAPOST || "",
        dimscale: t.DIMSCALE,
        dimasz: t.DIMASZ,
        dimexo: t.DIMEXO,
        dimdli: t.DIMDLI,
        dimexe: t.DIMEXE,
        dimrnd: t.DIMRND,
        dimdle: t.DIMDLE,
        dimtp: t.DIMTP,
        dimtm: t.DIMTM,
        dimtxt: t.DIMTXT,
        dimcen: t.DIMCEN,
        dimtsz: t.DIMTSZ,
        dimaltf: t.DIMALTF,
        dimlfac: t.DIMLFAC,
        dimtvp: t.DIMTVP,
        dimtfac: t.DIMTFAC,
        dimgap: t.DIMGAP,
        dimaltrnd: t.DIMALTRND,
        dimtol: t.DIMTOL == null || t.DIMTOL == 0 ? 0 : 1,
        dimlim: t.DIMLIM == null || t.DIMLIM == 0 ? 0 : 1,
        dimtih: t.DIMTIH == null || t.DIMTIH == 0 ? 0 : 1,
        dimtoh: t.DIMTOH == null || t.DIMTOH == 0 ? 0 : 1,
        dimse1: t.DIMSE1 == null || t.DIMSE1 == 0 ? 0 : 1,
        dimse2: t.DIMSE2 == null || t.DIMSE2 == 0 ? 0 : 1,
        dimtad: t.DIMTAD,
        dimzin: t.DIMZIN,
        dimazin: t.DIMAZIN,
        dimalt: t.DIMALT,
        dimaltd: t.DIMALTD,
        dimtofl: t.DIMTOFL,
        dimsah: t.DIMSAH,
        dimtix: t.DIMTIX,
        dimsoxd: t.DIMSOXD,
        dimclrd: t.DIMCLRD,
        dimclre: t.DIMCLRE,
        dimclrt: t.DIMCLRT,
        dimadec: t.DIMADEC || 0,
        dimunit: t.DIMUNIT || 2,
        dimdec: t.DIMDEC,
        dimtdec: t.DIMTDEC,
        dimaltu: t.DIMALTU,
        dimalttd: t.DIMALTTD,
        dimaunit: t.DIMAUNIT,
        dimfrac: t.DIMFRAC,
        dimlunit: t.DIMLUNIT,
        dimdsep: t.DIMDSEP,
        dimtmove: t.DIMTMOVE || 0,
        dimjust: t.DIMJUST,
        dimsd1: t.DIMSD1,
        dimsd2: t.DIMSD2,
        dimtolj: t.DIMTOLJ,
        dimtzin: t.DIMTZIN,
        dimaltz: t.DIMALTZ,
        dimalttz: t.DIMALTTZ,
        dimfit: t.DIMFIT || 0,
        dimupt: t.DIMUPT,
        dimatfit: t.DIMATFIT,
        dimtxsty: "Standard",
        // TODO: Set correct value
        dimldrblk: "",
        // TODO: Set correct value
        dimblk: t.DIMBLK || "",
        // TODO: Set correct value
        dimblk1: t.DIMBLK1 || "",
        // TODO: Set correct value
        dimblk2: t.DIMBLK2 || "",
        // TODO: Set correct value
        dimlwd: t.DIMLWD,
        dimlwe: t.DIMLWE
      }, r = new ae(o);
      this.processCommonTableEntryAttrs(t, r), n.tables.dimStyleTable.add(r);
    });
  }
  processLayers(e, n) {
    e.tables.LAYER.entries.forEach((t) => {
      const o = new le();
      o.colorIndex = t.colorIndex;
      const r = new de({
        name: t.name,
        standardFlags: t.standardFlag,
        linetype: t.lineType,
        lineWeight: t.lineweight,
        isOff: t.off,
        color: o,
        isPlottable: t.plotFlag != 0
      });
      this.processCommonTableEntryAttrs(t, r), n.tables.layerTable.add(r);
    });
  }
  processViewports(e, n) {
    e.tables.VPORT.entries.forEach((t) => {
      const o = new pe();
      this.processCommonTableEntryAttrs(t, o), t.circleSides && (o.circleSides = t.circleSides), o.standardFlag = t.standardFlag, o.center.copy(t.center), o.lowerLeftCorner.copy(t.lowerLeftCorner), o.upperRightCorner.copy(t.upperRightCorner), t.snapBasePoint && o.snapBase.copy(t.snapBasePoint), t.snapRotationAngle && (o.snapAngle = t.snapRotationAngle), t.snapSpacing && o.snapIncrements.copy(t.snapSpacing), t.majorGridLines && (o.gridMajor = t.majorGridLines), t.gridSpacing && o.gridIncrements.copy(t.gridSpacing), t.backgroundObjectId && (o.backgroundObjectId = t.backgroundObjectId), o.gsView.center.copy(t.center), o.gsView.viewDirectionFromTarget.copy(t.viewDirectionFromTarget), o.gsView.viewTarget.copy(t.viewTarget), t.lensLength && (o.gsView.lensLength = t.lensLength), t.frontClippingPlane && (o.gsView.frontClippingPlane = t.frontClippingPlane), t.backClippingPlane && (o.gsView.backClippingPlane = t.backClippingPlane), t.viewHeight && (o.gsView.viewHeight = t.viewHeight), t.viewTwistAngle && (o.gsView.viewTwistAngle = t.viewTwistAngle), t.frozenLayers && (o.gsView.frozenLayers = t.frozenLayers), t.styleSheet && (o.gsView.styleSheet = t.styleSheet), t.renderMode && (o.gsView.renderMode = t.renderMode), t.viewMode && (o.gsView.viewMode = t.viewMode), t.ucsIconSetting && (o.gsView.ucsIconSetting = t.ucsIconSetting), t.ucsOrigin && o.gsView.ucsOrigin.copy(t.ucsOrigin), t.ucsXAxis && o.gsView.ucsXAxis.copy(t.ucsXAxis), t.ucsYAxis && o.gsView.ucsYAxis.copy(t.ucsYAxis), t.orthographicType && (o.gsView.orthographicType = t.orthographicType), t.shadePlotSetting && (o.gsView.shadePlotSetting = t.shadePlotSetting), t.shadePlotObjectId && (o.gsView.shadePlotObjectId = t.shadePlotObjectId), t.visualStyleObjectId && (o.gsView.visualStyleObjectId = t.visualStyleObjectId), t.isDefaultLightingOn && (o.gsView.isDefaultLightingOn = t.isDefaultLightingOn), t.defaultLightingType && (o.gsView.defaultLightingType = t.defaultLightingType), t.brightness && (o.gsView.brightness = t.brightness), t.contrast && (o.gsView.contrast = t.contrast), t.ambientColor && (o.gsView.ambientColor = t.ambientColor), n.tables.viewportTable.add(o);
    });
  }
  processBlockTables(e, n) {
    e.tables.BLOCK_RECORD.entries.forEach((t) => {
      let o = n.tables.blockTable.getAt(t.name);
      o || (o = new ue(), o.objectId = t.handle.toString(), o.name = t.name, o.ownerId = t.ownerHandle.toString(), o.origin.copy(t.basePoint), o.layoutId = t.layout.toString(), n.tables.blockTable.add(o)), !o.isModelSapce && !o.isPaperSapce && t.entities && t.entities.length > 0 && this.processEntitiesInBlock(t.entities, o);
    });
  }
  processBlocks(e, n) {
  }
  async processEntitiesInBlock(e, n) {
    const s = new P(), t = e.length, o = [];
    for (let r = 0; r < t; r++) {
      const a = e[r], i = s.convert(a);
      i && o.push(i);
    }
    n.appendEntity(o);
  }
  /**
   * Breaks up the work into smaller chunks that are executed asynchronously. This is often referred to
   * as "batch processing" or "cooperative multitasking," where the time-consuming task is broken into
   * smaller pieces and executed in small intervals to allow the UI to remain responsive.
   */
  async processEntities(e, n, s, t, o) {
    const r = new P();
    let a = e.entities;
    const i = a.length, l = new fe(
      i,
      100 - t.value,
      s
    );
    this.config.convertByEntityType && (a = this.groupAndFlattenByType(a));
    const c = n.tables.blockTable.modelSpace;
    await l.processChunk(async (u, p) => {
      const f = [];
      for (let d = u; d < p; d++) {
        const h = a[d], g = r.convert(h);
        g && f.push(g);
      }
      if (c.appendEntity(f), o) {
        let d = t.value + p / i * (100 - t.value);
        d > 100 && (d = 100), await o(d, "ENTITY", "IN-PROGRESS");
      }
    });
  }
  processHeader(e, n) {
    const s = e.header;
    s.CECOLOR && (s.CECOLOR.index >= 0 && s.CECOLOR.index <= 256 ? n.cecolor.colorIndex = s.CECOLOR.index : n.cecolor.setRGBValue(s.CECOLOR.rgb)), n.angBase = s.ANGBASE ?? 0, n.angDir = s.ANGDIR ?? 0, n.aunits = s.AUNITS ?? 0, s.EXTMAX && (n.extmax = s.EXTMAX), s.EXTMIN && (n.extmin = s.EXTMIN), n.insunits = s.INSUNITS ?? 1, n.pdmode = s.PDMODE ?? 0, n.pdsize = s.PDSIZE ?? 0;
  }
  processCommonTableEntryAttrs(e, n) {
    n.name = e.name, n.objectId = e.handle.toString(), n.ownerId = e.ownerHandle.toString();
  }
  processObjects(e, n) {
    this.processLayouts(e, n), this.processImageDefs(e, n);
  }
  processLayouts(e, n) {
    const s = n.dictionaries.layouts;
    e.objects.LAYOUT.forEach((o) => {
      const r = new he();
      r.layoutName = o.layoutName, r.tabOrder = o.tabOrder;
      const a = n.tables.blockTable.newIterator();
      r.objectId = o.handle.toString();
      for (const i of a)
        if (i.layoutId === r.objectId) {
          r.blockTableRecordId = i.objectId;
          break;
        }
      r.blockTableRecordId || o.layoutName === "Model" && (r.blockTableRecordId = n.tables.blockTable.modelSpace.objectId), r.limits.min.copy(o.minLimit), r.limits.max.copy(o.maxLimit), r.extents.min.copy(o.minExtent), r.extents.max.copy(o.maxExtent), this.processCommonObjectAttrs(o, r), s.setAt(r.layoutName, r);
    });
  }
  processImageDefs(e, n) {
    const s = n.dictionaries.imageDefs;
    e.objects.IMAGEDEF.forEach((o) => {
      const r = new De();
      r.sourceFileName = o.fileName, this.processCommonObjectAttrs(o, r), s.setAt(r.objectId, r);
    });
  }
  processCommonObjectAttrs(e, n) {
    n.objectId = e.handle.toString(), n.ownerId = e.ownerHandle.toString();
  }
  /**
   * Groups entities by their `type` property and flattens the result into a single array.
   *
   * The order of `type` groups follows the order in which they first appear in the input array.
   * Items within each group preserve their original order.
   *
   * This runs in O(n) time, which is generally faster than sorting when you
   * don't care about alphabetical order of types.
   *
   * @param entities - The array of entities to group and flatten.
   *
   * @returns A new array of entities grouped by their `type` property.
   */
  groupAndFlattenByType(e) {
    const n = {}, s = [];
    for (const t of e)
      n[t.type] || (n[t.type] = [], s.push(t.type)), n[t.type].push(t);
    return s.flatMap((t) => n[t]);
  }
}
export {
  Ae as AcDbLibreDwgConverter
};
