import { AcDbFace as S, AcDbArc as C, AcGeVector3d as D, AcDbCircle as x, AcDbEllipse as v, AcDbLine as O, AcGePoint3d as y, AcDbSpline as T, AcDbPoint as k, AcDbTrace as m, AcDbPolyline as R, AcGePoint2d as b, AcDbPoly2dType as A, AcDb2dPolyline as V, AcDbPoly3dType as w, AcDb3dPolyline as F, AcDbHatch as N, AcGePolyline2d as B, AcGeLoop2d as j, AcGeLine2d as z, AcGeCircArc2d as W, AcGeVector2d as H, AcGeEllipseArc2d as X, AcGeSpline3d as P, AcDbTable as G, AcDbText as U, AcDbMText as Y, AcDbLeader as Z, AcDbAlignedDimension as _, AcDb3PointAngularDimension as K, AcDbOrdinateDimension as q, AcDbRadialDimension as J, AcDbDiametricDimension as Q, AcDbRasterImage as $, AcDbWipeout as ee, AcDbViewport as ne, AcDbRay as te, AcDbXline as oe, AcDbAttributeFlags as I, AcDbAttributeMTextFlag as E, AcDbAttribute as se, AcDbAttributeDefinition as re, AcDbBlockReference as ie, AcCmTransparency as ce, AcDbDatabaseConverter as ae, createWorkerApi as le, AcDbLinetypeTableRecord as de, AcDbTextStyleTableRecord as pe, AcDbDimStyleTableRecord as ue, AcCmColor as fe, AcDbLayerTableRecord as he, AcDbViewportTableRecord as De, AcDbBlockTableRecord as ge, AcDbBatchProcessing as Ae, AcDbLayout as Ie, AcDbRasterImageDef as we } from "@mlightcad/data-model";
class M {
  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 == "ATTDEF" ? this.convertAttributeDefinition(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 S();
    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 C(
      e.center,
      e.radius,
      e.startAngle,
      e.endAngle,
      e.extrusionDirection ?? D.Z_AXIS
    );
  }
  convertCirle(e) {
    return new x(
      e.center,
      e.radius,
      e.extrusionDirection ?? D.Z_AXIS
    );
  }
  convertEllipse(e) {
    const n = new D(e.majorAxisEndPoint), o = n.length();
    return new v(
      e.center,
      e.extrusionDirection ?? D.Z_AXIS,
      n,
      o,
      o * e.axisRatio,
      e.startAngle,
      e.endAngle
    );
  }
  convertLine(e) {
    const n = e.startPoint, o = e.endPoint;
    return new O(
      new y(n.x, n.y, n.z),
      new y(o.x, o.y, o.z)
    );
  }
  convertSpline(e) {
    try {
      if (e.numberOfControlPoints > 0 && e.numberOfKnots > 0)
        return new T(
          e.controlPoints,
          e.knots,
          e.weights,
          e.degree,
          !!(e.flag & 1)
        );
      if (e.numberOfFitPoints > 0)
        return new T(
          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 k();
    return n.position = e.position, n;
  }
  convertSolid(e) {
    const n = new m();
    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 R();
    return n.closed = !!(e.flag & 512), e.vertices.forEach((o, t) => {
      n.addVertexAt(
        t,
        new b(o.x, o.y),
        o.bulge,
        o.startWidth,
        o.endWidth
      );
    }), n;
  }
  convertPolyline2d(e) {
    const n = !!(e.flag & 1), o = [], t = [];
    e.vertices.map((r) => {
      r.flag & 16 || (o.push({
        x: r.x,
        y: r.y,
        z: r.z
      }), t.push(r.bulge ?? 0));
    });
    let s = A.SimplePoly;
    return e.flag & 2 ? s = A.FitCurvePoly : e.flag & 4 && (e.smoothType == 6 ? s = A.CubicSplinePoly : e.smoothType == 5 && (s = A.QuadSplinePoly)), new V(
      s,
      o,
      0,
      n,
      e.startWidth,
      e.endWidth,
      t
    );
  }
  convertPolyline3d(e) {
    const n = !!(e.flag & 1), o = [];
    e.vertices.map((s) => {
      s.flag & 16 || o.push({
        x: s.x,
        y: s.y,
        z: s.z
      });
    });
    let t = w.SimplePoly;
    return e.flag & 4 && (e.smoothType == 6 ? t = w.CubicSplinePoly : e.smoothType == 5 && (t = w.QuadSplinePoly)), new F(t, o, n);
  }
  convertHatch(e) {
    var t;
    const n = new N();
    return (t = e.definitionLines) == null || t.forEach((s) => {
      n.definitionLines.push({
        angle: s.angle,
        base: s.base,
        offset: s.offset,
        dashLengths: s.numberOfDashLengths > 0 ? s.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((s) => {
      if (s.boundaryPathTypeFlag & 2) {
        const a = s, i = new B();
        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 = s, i = new j();
        a.edges.forEach((l) => {
          if (l != null) {
            if (l.type == 1) {
              const c = l;
              i.add(new z(c.start, c.end));
            } else if (l.type == 2) {
              const c = l;
              i.add(
                new W(
                  c.center,
                  c.radius,
                  c.startAngle,
                  c.endAngle,
                  !c.isCCW
                )
              );
            } else if (l.type == 3) {
              const c = l;
              new H().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 X(
                  { ...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 P(
                    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 P(u, "Uniform"));
              }
            }
          }
        }), n.add(i);
      }
    }), n;
  }
  convertTable(e) {
    const n = new G(
      e.name,
      e.rowCount,
      e.columnCount
    );
    return n.attachmentPoint = e.attachmentPoint, n.position.copy(e.startPoint), e.columnWidthArr.forEach(
      (o, t) => n.setColumnWidth(t, o)
    ), e.rowHeightArr.forEach(
      (o, t) => n.setRowHeight(t, o)
    ), e.cells.forEach((o, t) => {
      n.setCell(t, o);
    }), n;
  }
  convertText(e) {
    const n = new U();
    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 Y();
    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 Z();
    return e.vertices.forEach((o) => {
      n.appendVertex(o);
    }), 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, o = new _(
        n.subDefinitionPoint1,
        n.subDefinitionPoint2,
        n.definitionPoint
      );
      return n.insertionPoint && (o.dimBlockPosition = {
        x: n.insertionPoint.x,
        y: n.insertionPoint.y,
        z: 0
      }), o.rotation = n.rotationAngle, this.processDimensionCommonAttrs(e, o), o;
    } else if (e.subclassMarker == "AcDb3PointAngularDimension") {
      const n = e, o = new K(
        n.centerPoint,
        n.subDefinitionPoint1,
        n.subDefinitionPoint2,
        n.definitionPoint
      );
      return this.processDimensionCommonAttrs(e, o), o;
    } else if (e.subclassMarker == "AcDbOrdinateDimension") {
      const n = e, o = new q(
        n.subDefinitionPoint1,
        n.subDefinitionPoint2
      );
      return this.processDimensionCommonAttrs(e, o), o;
    } else if (e.subclassMarker == "AcDbRadialDimension") {
      const n = e, o = new J(
        n.definitionPoint,
        n.centerPoint,
        n.leaderLength
      );
      return this.processDimensionCommonAttrs(e, o), o;
    } else if (e.subclassMarker == "AcDbDiametricDimension") {
      const n = e, o = new Q(
        n.definitionPoint,
        n.centerPoint,
        n.leaderLength
      );
      return this.processDimensionCommonAttrs(e, o), o;
    }
    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, 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((o) => {
      n.clipBoundary.push(new b(o));
    }), 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 $();
    return this.processImage(e, n), n;
  }
  convertWipeout(e) {
    const n = new ee();
    return this.processImage(e, n), n;
  }
  convertViewport(e) {
    const n = new ne();
    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 te();
    return n.basePoint.copy(e.firstPoint), n.unitDir.copy(e.unitDirection), n;
  }
  convertXline(e) {
    const n = new oe();
    return n.basePoint.copy(e.firstPoint), n.unitDir.copy(e.unitDirection), n;
  }
  convertAttributeCommon(e, n) {
    const o = e.text;
    n.textString = o.text, n.styleName = o.styleName, n.height = o.textHeight, n.position.copy(o.startPoint), n.rotation = o.rotation, n.oblique = o.obliqueAngle ?? 0, n.thickness = o.thickness, n.horizontalMode = o.halign, n.verticalMode = o.valign, n.widthFactor = o.xScale ?? 1, n.tag = e.tag, n.fieldLength = e.fieldLength, n.isInvisible = (e.flags & I.Invisible) !== 0, n.isConst = (e.flags & I.Const) !== 0, n.isVerifiable = (e.flags & I.Verifiable) !== 0, n.isPreset = (e.flags & I.Preset) !== 0, n.lockPositionInBlock = e.lockPositionFlag, n.isReallyLocked = e.isReallyLocked, n.isMTextAttribute = (e.mtextFlag & E.MultiLine) !== 0, n.isConstMTextAttribute = (e.mtextFlag & E.ConstMultiLine) !== 0;
  }
  convertAttribute(e) {
    const n = new se();
    return this.convertAttributeCommon(e, n), n;
  }
  convertAttributeDefinition(e) {
    const n = new re();
    return this.convertAttributeCommon(e, n), n.prompt = e.prompt, n;
  }
  convertBlockReference(e) {
    const n = new ie(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), e.attribs.forEach((o) => {
      const t = this.convertAttribute(o);
      n.appendAttributes(t);
    }), 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, n.ownerId = e.ownerBlockRecordSoftId, 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 o = new ce();
      o.method = e.transparencyType, (o.isByBlock || o.isByBlock) && (o.alpha = e.transparency), n.transparency = o;
    }
  }
}
const ye = "*MODEL_SPACE";
class be extends ae {
  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 = le({
        workerUrl: this.config.parserWorkerUrl,
        // One concurrent worker needed for parser
        maxConcurrentWorkers: 1
      }), o = await n.execute(e);
      if (n.destroy(), o.success)
        return o.data;
      throw new Error(
        `Failed to parse drawing due to error: '${o.error}'`
      );
    } 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 o = /* @__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), o.set(r.name, a);
    });
    const s = /* @__PURE__ */ new Set();
    return this.getFontsInBlock(e.entities, n, o, s), Array.from(s);
  }
  /**
   * Iterate entities in model space to get fonts used by text, mtext and insert entities
   */
  getFontsInBlock(e, n, o, t) {
    const s = /\\f(.*?)\|/g;
    e.forEach((r) => {
      if (r.type == "MTEXT") {
        const a = r;
        [...a.text.matchAll(s)].forEach((l) => {
          t.add(l[1].toLowerCase());
        });
        const i = o.get(a.styleName);
        i == null || i.forEach((l) => t.add(l));
      } else if (r.type == "TEXT") {
        const a = r, i = o.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, o, t);
      }
    });
  }
  processLineTypes(e, n) {
    e.tables.LTYPE.entries.forEach((t) => {
      const s = {
        name: t.name,
        description: t.description,
        standardFlag: t.standardFlag,
        totalPatternLength: t.totalPatternLength,
        pattern: t.pattern
      }, r = new de(s);
      this.processCommonTableEntryAttrs(t, r), r.name = t.name, n.tables.linetypeTable.add(r);
    });
  }
  processTextStyles(e, n) {
    e.tables.STYLE.entries.forEach((t) => {
      const s = new pe(t);
      this.processCommonTableEntryAttrs(t, s), n.tables.textStyleTable.add(s);
    });
  }
  processDimStyles(e, n) {
    e.tables.DIMSTYLE.entries.forEach((t) => {
      const s = {
        name: t.name,
        ownerId: t.ownerHandle,
        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 ue(s);
      this.processCommonTableEntryAttrs(t, r), n.tables.dimStyleTable.add(r);
    });
  }
  processLayers(e, n) {
    e.tables.LAYER.entries.forEach((t) => {
      const s = new fe();
      s.colorIndex = t.colorIndex;
      const r = new he({
        name: t.name,
        standardFlags: t.standardFlag,
        linetype: t.lineType,
        lineWeight: t.lineweight,
        isOff: t.off,
        color: s,
        isPlottable: t.plotFlag != 0
      });
      this.processCommonTableEntryAttrs(t, r), n.tables.layerTable.add(r);
    });
  }
  processViewports(e, n) {
    e.tables.VPORT.entries.forEach((t) => {
      const s = new De();
      this.processCommonTableEntryAttrs(t, s), t.circleSides && (s.circleSides = t.circleSides), s.standardFlag = t.standardFlag, s.center.copy(t.center), s.lowerLeftCorner.copy(t.lowerLeftCorner), s.upperRightCorner.copy(t.upperRightCorner), t.snapBasePoint && s.snapBase.copy(t.snapBasePoint), t.snapRotationAngle && (s.snapAngle = t.snapRotationAngle), t.snapSpacing && s.snapIncrements.copy(t.snapSpacing), t.majorGridLines && (s.gridMajor = t.majorGridLines), t.gridSpacing && s.gridIncrements.copy(t.gridSpacing), t.backgroundObjectId && (s.backgroundObjectId = t.backgroundObjectId), s.gsView.center.copy(t.center), s.gsView.viewDirectionFromTarget.copy(t.viewDirectionFromTarget), s.gsView.viewTarget.copy(t.viewTarget), t.lensLength && (s.gsView.lensLength = t.lensLength), t.frontClippingPlane && (s.gsView.frontClippingPlane = t.frontClippingPlane), t.backClippingPlane && (s.gsView.backClippingPlane = t.backClippingPlane), t.viewHeight && (s.gsView.viewHeight = t.viewHeight), t.viewTwistAngle && (s.gsView.viewTwistAngle = t.viewTwistAngle), t.frozenLayers && (s.gsView.frozenLayers = t.frozenLayers), t.styleSheet && (s.gsView.styleSheet = t.styleSheet), t.renderMode && (s.gsView.renderMode = t.renderMode), t.viewMode && (s.gsView.viewMode = t.viewMode), t.ucsIconSetting && (s.gsView.ucsIconSetting = t.ucsIconSetting), t.ucsOrigin && s.gsView.ucsOrigin.copy(t.ucsOrigin), t.ucsXAxis && s.gsView.ucsXAxis.copy(t.ucsXAxis), t.ucsYAxis && s.gsView.ucsYAxis.copy(t.ucsYAxis), t.orthographicType && (s.gsView.orthographicType = t.orthographicType), t.shadePlotSetting && (s.gsView.shadePlotSetting = t.shadePlotSetting), t.shadePlotObjectId && (s.gsView.shadePlotObjectId = t.shadePlotObjectId), t.visualStyleObjectId && (s.gsView.visualStyleObjectId = t.visualStyleObjectId), t.isDefaultLightingOn && (s.gsView.isDefaultLightingOn = t.isDefaultLightingOn), t.defaultLightingType && (s.gsView.defaultLightingType = t.defaultLightingType), t.brightness && (s.gsView.brightness = t.brightness), t.contrast && (s.gsView.contrast = t.contrast), t.ambientColor && (s.gsView.ambientColor = t.ambientColor), n.tables.viewportTable.add(s);
    });
  }
  processBlockTables(e, n) {
    e.tables.BLOCK_RECORD.entries.forEach((t) => {
      let s = n.tables.blockTable.getAt(t.name);
      s || (s = new ge(), s.objectId = t.handle, s.name = t.name, s.ownerId = t.ownerHandle, s.origin.copy(t.basePoint), s.layoutId = t.layout, n.tables.blockTable.add(s)), !s.isModelSapce && t.entities && t.entities.length > 0 && this.processEntitiesInBlock(t.entities, s);
    });
  }
  processBlocks(e, n) {
  }
  async processEntitiesInBlock(e, n) {
    const o = new M(), t = e.length, s = [];
    for (let r = 0; r < t; r++) {
      const a = e[r], i = o.convert(a);
      i && s.push(i);
    }
    n.appendEntity(s);
  }
  /**
   * 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, o, t, s) {
    const r = new M();
    let a = [];
    e.tables.BLOCK_RECORD.entries.forEach((u) => {
      this.isModelSpace(u.name) && (a = u.entities);
    });
    const i = a.length, l = new Ae(
      i,
      100 - t.value,
      o
    );
    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), s) {
        let d = t.value + p / i * (100 - t.value);
        d > 100 && (d = 100), await s(d, "ENTITY", "IN-PROGRESS");
      }
    });
  }
  processHeader(e, n) {
    const o = e.header;
    o.CECOLOR && (o.CECOLOR.index >= 0 && o.CECOLOR.index <= 256 ? n.cecolor.colorIndex = o.CECOLOR.index : n.cecolor.setRGBValue(o.CECOLOR.rgb)), n.angBase = o.ANGBASE ?? 0, n.angDir = o.ANGDIR ?? 0, n.aunits = o.AUNITS ?? 0, n.celtscale = o.CELTSCALE ?? 1, n.ltscale = o.LTSCALE ?? 1, o.EXTMAX && (n.extmax = o.EXTMAX), o.EXTMIN && (n.extmin = o.EXTMIN), n.insunits = o.INSUNITS ?? 1, n.pdmode = o.PDMODE ?? 0, n.pdsize = o.PDSIZE ?? 0;
  }
  processCommonTableEntryAttrs(e, n) {
    n.name = e.name, n.objectId = e.handle, n.ownerId = e.ownerHandle;
  }
  processObjects(e, n) {
    this.processLayouts(e, n), this.processImageDefs(e, n);
  }
  processLayouts(e, n) {
    const o = n.dictionaries.layouts;
    e.objects.LAYOUT.forEach((s) => {
      const r = new Ie();
      r.layoutName = s.layoutName, r.tabOrder = s.tabOrder;
      const a = n.tables.blockTable.newIterator();
      r.objectId = s.handle;
      for (const i of a)
        if (i.layoutId === r.objectId) {
          r.blockTableRecordId = i.objectId;
          break;
        }
      r.blockTableRecordId || s.layoutName === "Model" && (r.blockTableRecordId = n.tables.blockTable.modelSpace.objectId), r.limits.min.copy(s.minLimit), r.limits.max.copy(s.maxLimit), r.extents.min.copy(s.minExtent), r.extents.max.copy(s.maxExtent), this.processCommonObjectAttrs(s, r), o.setAt(r.layoutName, r);
    });
  }
  processImageDefs(e, n) {
    const o = n.dictionaries.imageDefs;
    e.objects.IMAGEDEF.forEach((s) => {
      const r = new we();
      r.sourceFileName = s.fileName, this.processCommonObjectAttrs(s, r), o.setAt(r.objectId, r);
    });
  }
  processCommonObjectAttrs(e, n) {
    n.objectId = e.handle, n.ownerId = e.ownerHandle;
  }
  /**
   * 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 = {}, o = [];
    for (const t of e)
      n[t.type] || (n[t.type] = [], o.push(t.type)), n[t.type].push(t);
    return o.flatMap((t) => n[t]);
  }
  isModelSpace(e) {
    return e && e.toUpperCase() == ye;
  }
}
export {
  be as AcDbLibreDwgConverter
};
