Added alternative DXF/DWG Importer

This commit is contained in:
Mario Voigt 2020-08-23 23:25:47 +02:00
parent b2f38aab94
commit bb4d9afa44
1183 changed files with 77102 additions and 0 deletions

View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>DXF/DWG Importer</name>
<id>fablabchemnitz.de.dxfdwgimporter_configure</id>
<hbox>
<vbox>
<label appearance="header">General</label>
<separator/>
<param name="dxf_to_svg_parser" gui-text="DXF to SVG parser" type="optiongroup" appearance="combo">
<option value="bjnortier">bjnortier DXF (good quality, some polygon artifacts, very quick, correct scaling)</option>
<option value="uniconverter">sk1 UniConverter (best output, but fails sometimes, unknown scaling)</option>
<option value="ezdxf">ezdxf (higher quality, many single nodes, unknown scaling)</option>
</param>
<param name="resizetoimport" type="bool" gui-text="Resize the canvas to the imported drawing's bounding box">true</param>
<param name="extraborder" type="float" precision="3" gui-text="Add extra border around fitted canvas">0.0</param>
<param name="extraborder_units" type="optiongroup" appearance="combo" gui-text="Border offset units">
<option value="mm">mm</option>
<option value="cm">cm</option>
<option value="in">in</option>
<option value="pt">pt</option>
<option value="px">px</option>
</param>
<spacer/>
<label appearance="header">ODA File Converter - DWG to DXF / DXF to DXF</label>
<separator/>
<param name="odafileconverter" type="path" gui-text="ODAFileConverter.exe" gui-description="Full path to 'ODAFileConverter.exe'" filetypes="exe" mode="file">C:\Program Files\ODA\ODAFileConverter_title 21.6.0\ODAFileConverter.exe</param>
<param name="outputformat" gui-text="AutoCAD output version" type="optiongroup" appearance="combo">
<!-- Unsupported stuff:
<option value="ACAD2018_DWG">2018 DWG</option>
<option value="ACAD2013_DWG">2013 DWG</option>
<option value="ACAD2010_DWG">2010 DWG</option>
<option value="ACAD2007_DWG">2007 DWG</option>
<option value="ACAD2004_DWG">2004 DWF</option>
<option value="ACAD2000_DWG">2000 DWG</option>
<option value="ACAD14_DWG">R14 DWG</option>
<option value="ACAD13_DWG">R13 DWG</option>
<option value="ACAD12_DWG">R12 DWG</option>
-->
<option value="ACAD2018_DXF">2018 ASCII DXF</option>
<option value="ACAD2013_DXF">2013 ASCII DXF</option>
<option value="ACAD2010_DXF">2010 ASCII DXF</option>
<option value="ACAD2007_DXF">2007 ASCII DXF</option>
<option value="ACAD2004_DXF">2004 ASCII DXF</option>
<option value="ACAD2000_DXF">2000 ASCII DXF</option>
<option value="ACAD14_DXF">R14 ASCII DXF</option>
<option value="ACAD13_DXF">R13 ASCII DXF</option>
<option value="ACAD12_DXF">R12 ASCII DXF</option>
<option value="ACAD10_DXF">R10 ASCII DXF</option>
<option value="ACAD9_DXF">R9 ASCII DXF</option>
<!-- Unsupported stuff:
<option value="ACAD2018_DXB">2018 Binary DXF</option>
<option value="ACAD2013_DXB">2013 Binary DXF</option>
<option value="ACAD2010_DXB">2010 Binary DXF</option>
<option value="ACAD2007_DXB">2007 Binary DXF</option>
<option value="ACAD2004_DXB">2004 Binary DXF</option>
<option value="ACAD2000_DXB">2000 Binary DXF</option>
<option value="ACAD14_DXB">R14 Binary DXF</option>
<option value="ACAD13_DXB">R13 Binary DXF</option>
<option value="ACAD12_DXB">R12 Binary DXF</option>
<option value="ACAD10_DXB">R10 Binary DXF</option>
-->
</param>
<param name="odahidewindow" type="bool" gui-text="Hide ODA GUI window" gui-description="Hide ODA GUI window">true</param>
<param name="skip_dxf_to_dxf" type="bool" gui-text="Skip conversion from DXF to DXF" gui-description="This will skip ODA File Converter execution if input is already DXF file. Might save some seconds of time and maybe prevents errors.">false</param>
<param name="audit_repair" type="bool" gui-text="Perform audit (auto-repair)">true</param>
<spacer/>
<label appearance="header">sk1 UniConverter 1.1.X - DXF to SVG</label>
<separator/>
<param name="sk1uniconverter" type="path" gui-text="uniconvertor.cmd" gui-description="Full path to 'uniconvertor.cmd'" filetypes="cmd" mode="file">C:\Program Files (x86)\sK1 Project\UniConvertor-1.1.6\uniconvertor.cmd</param>
<param name="opendironerror" type="bool" gui-text="Open containing output directory on sk1 conversion errors">true</param>
</vbox>
<spacer/>
<separator/>
<spacer/>
<vbox>
<label appearance="header">ezdxf DXF to DXF Pre-Processing (Filter)</label>
<separator/>
<label>This will apply regardless of the choice of the DXF to SVG converter.</label>
<param name="ezdxf_preprocessing" type="bool" gui-text="Filter entities with ezdxf (recommended if you use sk1 UniConverter)">true</param>
<param name="ezdxf_output_version" type="optiongroup" appearance="combo" gui-text="ezdxf output version">
<option value="SAME">Same as AutoCAD output version</option>
<option value="R2018">2018 ASCII DXF</option>
<option value="R2013">2013 ASCII DXF</option>
<option value="R2010">2010 ASCII DXF</option>
<option value="R2007">2007 ASCII DXF</option>
<option value="R2004">2004 ASCII DXF</option>
<option value="R2000">2000 ASCII DXF</option>
</param>
<label>What entity types do you want to filter? Only the listed one's are possible at the moment.</label>
<param name="allentities" type="bool" gui-text="Use all entities (override selection)">false</param>
<hbox>
<vbox>
<param type="bool" gui-text="3DFACE" name="THREE_DFACE">true</param>
<param type="bool" gui-text="ARC" name="ARC">true</param>
<param type="bool" gui-text="BLOCK" name="BLOCK">true</param>
<param type="bool" gui-text="CIRCLE" name="CIRCLE">true</param>
<param type="bool" gui-text="ELLIPSE" name="ELLIPSE">true</param>
<param type="bool" gui-text="LINE" name="LINE">true</param>
<param type="bool" gui-text="LWPOLYLINE" name="LWPOLYLINE">true</param>
<param type="bool" gui-text="POINT" name="POINT">true</param>
</vbox>
<separator/>
<vbox>
<param type="bool" gui-text="POLYLINE" name="POLYLINE">true</param>
<param type="bool" gui-text="POP_TRAFO" name="POP_TRAFO">true</param>
<param type="bool" gui-text="SEQEND" name="SEQEND">true</param>
<param type="bool" gui-text="SOLID" name="SOLID">true</param>
<param type="bool" gui-text="SPLINE" name="SPLINE">true</param>
<param type="bool" gui-text="TABLE" name="TABLE">true</param>
<param type="bool" gui-text="VERTEX" name="VERTEX">true</param>
<param type="bool" gui-text="VIEWPORT" name="VIEWPORT">true</param>
</vbox>
</hbox>
</vbox>
</hbox>
<label appearance="header">Import File (*.dxf, .dwg)</label>
<separator/>
<param name="inputfile" type="path" gui-text="File path" gui-description="Full path to your file, e.g. 'C:\Users\Username\Documents\myimage.jpg'" filetypes="dxf,dwg" mode="file">C:\Users\</param>
<spacer/>
<label appearance="header">About</label>
<separator/>
<label>DXF/DWG File Importer by Mario Voigt / Stadtfabrikanten e.V. (2020)</label>
<label>A strange looking ODA File Converter/sk1 UniConverter/ezdxf tool chain. But it works! The most versatile tool to import much hated AutoCAD data for InkScape yet.</label>
<label appearance="url">https://fablabchemnitz.de</label>
<label>License: GNU GPL v3</label>
<effect needs-live-preview="true">
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Import/Export/Transfer"/>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">dxfdwgimporter.py</command>
</script>
</inkscape-extension>

View File

@ -0,0 +1,289 @@
#!/usr/bin/env python3
"""
Extension for InkScape 1.0
Import any DWG or DXF file using ODA File Converter, sk1 UniConverter, ezdxf and more tools.
Author: Mario Voigt / FabLab Chemnitz
Mail: mario.voigt@stadtfabrikanten.org
Date: 23.08.2020
Last patch: 23.08.2020
License: GNU GPL v3
Module licenses
- ezdxf (https://github.com/mozman/ezdxf) - MIT License
- node.js (https://raw.githubusercontent.com/nodejs/node/master/LICENSE) - MIT License
- https://github.com/bjnortier/dxf - MIT License
- ODA File Converter - not bundled (due to restrictions by vendor)
- sk1 UniConverter (https://github.com/sk1project/uniconvertor) - AGPL v3.0 - not bundled
"""
import inkex
import sys
import os
import re
import subprocess, tempfile
from lxml import etree
from subprocess import Popen, PIPE
import shutil
from pathlib import Path
#ezdxf related imports
import matplotlib.pyplot as plt
import ezdxf
from ezdxf.addons.drawing import RenderContext, Frontend
from ezdxf.addons.drawing.matplotlib_backend import MatplotlibBackend
from ezdxf.addons import Importer
class DXFDWGImport(inkex.Effect):
def __init__(self):
inkex.Effect.__init__(self)
self.arg_parser.add_argument("--odafileconverter", default=r"C:\Program Files\ODA\ODAFileConverter_title 21.6.0\ODAFileConverter.exe", help="Full path to 'ODAFileConverter.exe'")
self.arg_parser.add_argument("--odahidewindow", type=inkex.Boolean, default=True, help="Hide ODA GUI window")
self.arg_parser.add_argument("--outputformat", default="ACAD2018_DXF", help="ODA AutoCAD Output version")
self.arg_parser.add_argument("--sk1uniconverter", default=r"C:\Program Files (x86)\sK1 Project\UniConvertor-1.1.6\uniconvertor.cmd", help="Full path to 'uniconvertor.cmd'")
self.arg_parser.add_argument("--opendironerror", type=inkex.Boolean, default=True, help="Open containing output directory on conversion errors")
self.arg_parser.add_argument("--skip_dxf_to_dxf", type=inkex.Boolean, default=False, help="Skip conversion from DXF to DXF")
self.arg_parser.add_argument("--audit_repair", type=inkex.Boolean, default=True, help="Perform audit / autorepair")
self.arg_parser.add_argument("--dxf_to_svg_parser", default="bjnortier", help="Choose a DXF to SVG parser")
self.arg_parser.add_argument("--resizetoimport", type=inkex.Boolean, default=True, help="Resize the canvas to the imported drawing's bounding box")
self.arg_parser.add_argument("--THREE_DFACE", type=inkex.Boolean, default=True) #3DFACE
self.arg_parser.add_argument("--ARC", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--BLOCK", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--CIRCLE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--ELLIPSE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--LINE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--LWPOLYLINE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--POINT", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--POLYLINE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--POP_TRAFO", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--SEQEND", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--SOLID", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--SPLINE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--TABLE", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--VERTEX", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--VIEWPORT", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--inputfile")
self.arg_parser.add_argument("--extraborder", type=float, default=0.0)
self.arg_parser.add_argument("--extraborder_units")
self.arg_parser.add_argument("--ezdxf_output_version", default="SAME")
self.arg_parser.add_argument("--ezdxf_preprocessing", type=inkex.Boolean, default=True)
self.arg_parser.add_argument("--allentities", type=inkex.Boolean, default=True)
def effect(self):
#get input file and copy it to some new temporary directory
inputfile = self.options.inputfile
temp_input_dir = os.path.join(tempfile.gettempdir(),"inkscape-oda-convert-input")
#remove the input directory before doing new job
shutil.rmtree(temp_input_dir, ignore_errors=True)
if not os.path.exists(temp_input_dir):
os.mkdir(temp_input_dir) #recreate blank dir
shutil.copy2(inputfile, os.path.join(temp_input_dir, Path(inputfile).name)) # complete target filename given
#Prepapre output conversion
outputfilebase = os.path.splitext(os.path.splitext(os.path.basename(inputfile))[0])[0]
inputfile_ending = os.path.splitext(os.path.splitext(os.path.basename(inputfile))[1])[0]
temp_output_dir = os.path.join(tempfile.gettempdir(),"inkscape-oda-convert-output")
#remove the output directory before doing new job
shutil.rmtree(temp_output_dir, ignore_errors=True)
if not os.path.exists(temp_output_dir):
os.mkdir(temp_output_dir)
autocad_version = self.options.outputformat.split("_")[0]
autocad_format = self.options.outputformat.split("_")[1]
if self.options.audit_repair: #overwrite string bool with int value
self.options.audit_repair = "1"
else:
self.options.audit_repair = "0"
entityspace = []
if self.options.allentities or self.options.THREE_DFACE: entityspace.append("3DFACE")
if self.options.allentities or self.options.ARC: entityspace.append("ARC")
if self.options.allentities or self.options.BLOCK: entityspace.append("BLOCK")
if self.options.allentities or self.options.CIRCLE: entityspace.append("CIRCLE")
if self.options.allentities or self.options.ELLIPSE: entityspace.append("ELLIPSE")
if self.options.allentities or self.options.LINE: entityspace.append("LINE")
if self.options.allentities or self.options.LWPOLYLINE: entityspace.append("LWPOLYLINE")
if self.options.allentities or self.options.POINT: entityspace.append("POINT")
if self.options.allentities or self.options.POLYLINE: entityspace.append("POLYLINE")
if self.options.allentities or self.options.POP_TRAFO: entityspace.append("POP_TRAFO")
if self.options.allentities or self.options.SEQEND: entityspace.append("SEQEND")
if self.options.allentities or self.options.SOLID: entityspace.append("SOLID")
if self.options.allentities or self.options.SPLINE: entityspace.append("SPLINE")
if self.options.allentities or self.options.TABLE: entityspace.append("TABLE")
if self.options.allentities or self.options.VERTEX: entityspace.append("VERTEX")
if self.options.allentities or self.options.VIEWPORT: entityspace.append("VIEWPORT")
#ODA to ezdxf mapping
oda_ezdxf_mapping = []
oda_ezdxf_mapping.append(["ACAD9","R12","AC1004"]) #this mapping is not supported directly. so we use the lowest possible which is R12
oda_ezdxf_mapping.append(["ACAD10","R12","AC1006"]) #this mapping is not supported directly. so we use the lowest possible which is R12
oda_ezdxf_mapping.append(["ACAD12","R12","AC1009"])
oda_ezdxf_mapping.append(["ACAD13","R2000","AC1012"]) #R13 was overwritten by R2000 which points to AC1015 instead of AC1014 (see documentation)
oda_ezdxf_mapping.append(["ACAD14","R2000","AC1014"]) #R14 was overwritten by R2000 which points to AC1015 instead of AC1014 (see documentation)
oda_ezdxf_mapping.append(["ACAD2000","R2000","AC1015"])
oda_ezdxf_mapping.append(["ACAD2004","R2004","AC1018"])
oda_ezdxf_mapping.append(["ACAD2007","R2007","AC1021"])
oda_ezdxf_mapping.append(["ACAD2010","R2010","AC1024"])
oda_ezdxf_mapping.append(["ACAD2013","R2013","AC1027"])
oda_ezdxf_mapping.append(["ACAD2018","R2018","AC1032"])
ezdxf_autocad_format = None
for oe in oda_ezdxf_mapping:
if oe[0] == autocad_version:
ezdxf_autocad_format = oe[1]
break
if ezdxf_autocad_format is None:
inkex.errormsg("ezdxf conversion format version unknown")
if self.options.skip_dxf_to_dxf == False or inputfile_ending == ".dwg":
# Build and run ODA File Converter command // "cmd.exe /c start \"\" /MIN /WAIT"
oda_cmd = [self.options.odafileconverter, temp_input_dir, temp_output_dir, autocad_version, autocad_format, "0", self.options.audit_repair]
if self.options.odahidewindow:
info = subprocess.STARTUPINFO() #hide the ODA File Converter window because it is annoying
info.dwFlags = 1
info.wShowWindow = 0
proc = subprocess.Popen(oda_cmd, startupinfo=info, shell=False, stdout=PIPE, stderr=PIPE)
else: proc = subprocess.Popen(oda_cmd, shell=False, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
inkex.errormsg("ODA File Converter failed: %d %s %s" % (proc.returncode, stdout, stderr))
if self.options.skip_dxf_to_dxf: #if true we need to move the file to simulate "processed"
shutil.move(os.path.join(temp_input_dir, Path(inputfile).name), os.path.join(temp_output_dir, Path(inputfile).name))
# Prepare files
dxf_file = os.path.join(temp_output_dir, outputfilebase + ".dxf")
svg_file = os.path.join(temp_output_dir, outputfilebase + ".svg")
# Preprocessing DXF to DXF (entity filter)
if self.options.ezdxf_preprocessing:
#uniconverter does not handle all entities. we parse the file to exlude stuff which lets uniconverter fail
dxf = ezdxf.readfile(dxf_file)
modelspace = dxf.modelspace()
allowed_entities = []
# supported entities by UniConverter- impossible: MTEXT TEXT INSERT and a lot of others
query_string = str(entityspace)[1:-1].replace("'","").replace(",","")
for e in modelspace.query(query_string):
allowed_entities.append(e)
#inkex.utils.debug(ezdxf_autocad_format)
#inkex.utils.debug(self.options.ezdxf_output_version)
if self.options.ezdxf_output_version == "SAME":
doc = ezdxf.new(ezdxf_autocad_format)
else:
doc = ezdxf.new(self.options.ezdxf_output_version) #use the string values from inx file. Required to match the values from ezdxf library. See Python reference
msp = doc.modelspace()
for e in allowed_entities:
msp.add_foreign_entity(e)
doc.saveas(dxf_file)
# make SVG from DXF
if self.options.dxf_to_svg_parser == "uniconverter":
uniconverter_cmd = [self.options.sk1uniconverter, dxf_file, svg_file]
#inkex.utils.debug(uniconverter_cmd)
proc = subprocess.Popen(uniconverter_cmd, shell=False, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
inkex.errormsg("UniConverter failed: %d %s %s" % (proc.returncode, stdout, stderr))
if self.options.opendironerror:
subprocess.Popen(["explorer",temp_output_dir],close_fds=True)
elif self.options.dxf_to_svg_parser == "bjnortier":
bjnortier_cmd = ["node", os.path.join("node_modules","dxf","lib","cli.js"), dxf_file, svg_file]
#inkex.utils.debug(bjnortier_cmd)
proc = subprocess.Popen(bjnortier_cmd, shell=False, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
inkex.errormsg("node.js DXF to SVG conversion failed: %d %s %s" % (proc.returncode, stdout, stderr))
if self.options.opendironerror:
subprocess.Popen(["explorer",temp_output_dir],close_fds=True)
elif self.options.dxf_to_svg_parser == "ezdxf":
doc = ezdxf.readfile(dxf_file)
#doc.header['$DIMSCALE'] = 0.2 does not apply to the plot :-(
#inkex.utils.debug(doc.header['$DIMSCALE'])
#inkex.utils.debug(doc.header['$MEASUREMENT'])
auditor = doc.audit() #audit & repair DXF document before rendering
# The auditor.errors attribute stores severe errors, which *may* raise exceptions when rendering.
if len(auditor.errors) == 0:
fig = plt.figure()
ax = plt.axes([0., 0., 1., 1.], frameon=False, xticks=[], yticks=[])
#ax.patches = []
plt.axis('off')
plt.margins(0, 0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
out = MatplotlibBackend(fig.add_axes(ax))
Frontend(RenderContext(doc), out).draw_layout(doc.modelspace(), finalize=True)
#plt.show()
#fig.savefig(os.path.join(temp_output_dir, outputfilebase + ".png"), dpi=300)
fig.savefig(svg_file) #see https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.savefig.html
else:
inkex.utils.debug("undefined parser")
exit(1)
# Write the generated SVG into canvas
stream = open(svg_file, 'r')
p = etree.XMLParser(huge_tree=True)
doc = etree.parse(stream, parser=etree.XMLParser(huge_tree=True)).getroot()
stream.close()
#newGroup = self.document.getroot().add(inkex.Group())
doc.set('id', self.svg.get_unique_id('dxf_dwg_import'))
self.document.getroot().append(doc)
#get children of the doc and move them one group above - we don't do this for bjnortier tool because this has different structure which we don't want to disturb
if self.options.dxf_to_svg_parser == "uniconverter":
elements = []
emptyGroup = None
for firstGroup in doc.getchildren():
emptyGroup = firstGroup
for element in firstGroup.getchildren():
elements.append(element)
#break #only one cycle - could be bad idea or not
for element in elements:
doc.set('id', self.svg.get_unique_id('dxf_dwg_import'))
doc.insert(doc.index(firstGroup), element)
if emptyGroup is not None:
emptyGroup.getparent().remove(emptyGroup)
#empty the following vals because they destroy the size aspects of the import
if self.options.dxf_to_svg_parser == "bjnortier":
doc.set('width','')
doc.set('height','')
doc.set('viewBox','')
doc.getchildren()[0].set('transform','')
#adjust viewport and width/height to have the import at the center of the canvas - unstable at the moment.
if self.options.resizetoimport:
elements = []
for child in doc.getchildren():
#if child.tag == inkex.addNS('g','svg'):
elements.append(child)
#build some of bounding boxes and ignore errors for faulty elements (sum function often fails for that usecase!)
bbox = None
try:
bbox = elements[0].bounding_box() #init with the first bounding box of the tree (and hope that it is not a faulty one)
except:
pass
count = 0
for element in elements:
if count == 0: continue #skip the first
try:
bbox.add(element.bounding_box())
except:
pass
count += 1 #some stupid counter
if bbox is not None:
root = self.svg.getElement('//svg:svg');
offset = self.svg.unittouu(str(self.options.extraborder) + self.options.extraborder_units)
root.set('viewBox', '%f %f %f %f' % (bbox.left - offset, bbox.top - offset, bbox.width + 2 * offset, bbox.height + 2 * offset))
root.set('width', bbox.width + 2 * offset)
root.set('height', bbox.height + 2 * offset)
DXFDWGImport().run()

Binary file not shown.

View File

@ -0,0 +1,39 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": [
"plugin:react/recommended", "standard", "standard-react"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly",
"describe": "readonly",
"it": "readonly",
"before": "readonly",
"after": "readonly",
"beforeEach": "readonly",
"afterEach": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"react", "babel"
],
"parser": "babel-eslint",
"rules": {
"jest/valid-describe": 0
},
"settings": {
"react": {
"version": "detect"
}
}
}

View File

@ -0,0 +1,6 @@
language: node_js
node_js:
- "8"
- "10"
install: npm install
sudo: false

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2018 Ben Nortier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,126 @@
[![Build Status](https://travis-ci.org/bjnortier/dxf.svg?branch=master)](https://travis-ci.org/bjnortier/dxf)
# dxf
DXF parser for node/browser.
Uses several ES6 features in the source code (import, classes, let, const, arrows) but is packaged using babel so you can use it legacy JS environments.
Version 2.0 is a complete rewrite from the first attempt to write it in a SAX style, which wasn't really appropriate for a document with nested references (e.g inserts referencing blocks, nested inserts).
Version 3.0 converted the codebase to use [standard JS](https://standardjs.com), ES6 imports, stopped using Gulp, and updated & removed some dependencies.
Version 4.x is in progress and the aim is to use native SVG elements where possible, e.g. `<circle />`, `<ellipse />` etc. 4.0 introduces the `<circle />` element.
At this point in time, the important geometric entities are supported, but notably:
* MTEXT
* DIMENSION
* STYLE
* HATCH
and some others are **parsed**, but are **not supported for SVG rendering** (see section below on SVG rendering)
## Getting started
There is an ES5 and ES6 example in the ```examples/``` directory that show how to use the library. There are exposed functions for advanced users, but for the majority of users you can use the `Helper` object to get the data you're interested in (or convert to SVG):
```
const helper = new Helper(<DXF String>)
// The 1-to-1 object representation of the DXF
console.log('parsed:', helper.parsed)
// Denormalised blocks inserted with transforms applied
console.log('denormalised:', helper.denormalised)
// Create an SVG
console.log('svg:', helper.toSVG())
// Create polylines (e.g. to render in WebGL)
console.log('polylines:', helper.toPolylines())
```
## Running the Examples
Node ES5. Will write an SVG to `examples/example.es5.svg`:
```
$ node examples/example.es5.js
```
Node ES6. Will write an SVG to `examples/example.es6.svg`:
```
$ npx babel-node examples/example.es6.js
```
Browser. Compile to a browser bundle and open the example webpage:
```
$ npm run compile
$ open examples/dxf.html
```
## SVG
Geometric elements are supported, but dimensions, text, hatches and styles (except for line colors) are ***not***.
Native SVG elements are used as far as possible for curved entities (`<circle />`, `<ellipse/>` etc.), ***except for the SPLINE entity***, which is interpolated.
Here's an example you will find in the functional test output:
![svg example image](https://cloud.githubusercontent.com/assets/57994/17583566/e00f5d78-5fb1-11e6-9030-55686f980e6f.png)
## Interpolation
The library supports outputting DXFs as interpolated polylines for custom rendering (e.g. WebGL) or other applications, by using:
```
> helper.toPolylines()
```
## Command line
There is a command-line utility (courtesy of [@Joge97](https://github.com/Joge97)) for converting DXF files to SVG:
```
$ npm i -g dxf
$ dxf-to-svg
Usage: dxf-to-svg [options] <dxfFile> [svgFile]
Converts a dxf file to a svg file.
Options:
-V, --version output the version number
-v --verbose Verbose output
-h, --help output usage information
```
## Tests
Running
```$ npm test```
will execute the unit tests.
```$ npm run test:functional``` will run the functional tests in a browser. Please open `toSVG.html` when the file listing loads in the browser (or open `http://localhost:8030/toSVG.html#/`).
### Contributors
- Liam Mitchell https://github.com/LiamKarlMitchell
- Artur Zochniak https://github.com/arjamizo
- Andy Werner https://github.com/Gallore
- Ivan Baktsheev https://github.com/apla
- Jeff Chen https://github.com/jeffontheground
- Markko Paas https://github.com/markkopaas
- Kim Lokøy https://github.com/klokoy
- Erik Söhnel https://github.com/hoeck
- Teja https://github.com/hungerpirat
- Jakob Pallhuber https://github.com/Joge97
- Eric Mansfield https://github.com/ericman314

View File

@ -0,0 +1,41 @@
4.3.0
- #51 Fix bug when transforming empty bounding box
4.2.4
- #50 Fix knot piecewise beziers
4.2.3
- More accurate bounding boxes for arcs and ellipses (#48)
4.2.2
- Bump eslint-utils from 1.3.1 to 1.4.2
- Add HATCH to unsupported SVG entities in README
4.2.1
- Use main lodash package due to security issue(s)
4.2.0
- README updates
4.1.1
- #issue42 support entities that have extrusionZ === -1 defined on the entity itself (as opposed to the transform).
4.1.0
- CIRCLE DXF entities now produce native <circle /> SVG elements.
- ELLIPSE DXF entities now produce native <path d="A..."/> or <ellipse /> SVG elements.
- ARC DXF entities now produce native <path d="A..."/> or <ellipse /> SVG elements.
4.0.1
- Browser example uses Helper
4.0.0
- Use ES6 string interpolation in SVG generation.
- Use native SVG <circle /> elements for CIRCLE entities.
- Use SVG <g/> elements with a transform attribute for native and interpolated entities.
- Add a Helper object to simplify the workflow.
- The SVG output uses a root transform to flip the Y coordinates.
3.6.0
- NPM audit fixes.
- Remove support for Node v6 in Travis.
- Node engine is now >= 8.9.0.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>DXF Browser Example</title>
<script src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.2/require.min.js'></script>
</head>
<body>
<input type='file' id='file'/>
<div>Number of entities:<span id='numberOfEntities'>-</span></div>
<div id="svg"></div>
<script>
var numberOfEntities = document.getElementById('numberOfEntities')
var svgContainer = document.getElementById('svg')
var fileInput = document.getElementById('file')
window.requirejs(['../dist/dxf'], function(dxf) {
dxf.config.verbose = true
fileInput.addEventListener('change', function(event) {
var file = event.target.files[0]
var reader = new FileReader()
numberOfEntities.innerHTML = 'reading...'
reader.onload = function(e) {
if (e.target.readyState === 2) {
var dxfContents = e.target.result
var helper = new dxf.Helper(dxfContents)
numberOfEntities.innerHTML = helper.denormalised.length
const svg = helper.toSVG()
svgContainer.innerHTML = svg
}
}
reader.readAsBinaryString(file)
})
});
</script>
</body>
</html>

View File

@ -0,0 +1,29 @@
const fs = require('fs')
const join = require('path').join
const Helper = require('..').Helper
const helper = new Helper(fs.readFileSync(
'./test/resources/Ceco.NET-Architecture-Tm-53.dxf', 'utf-8'))
// The parsed entities
const { blocks, entities } = helper.parsed
console.log(`parsed: ${blocks.length} blocks, ${entities.length} entities.\n`)
// Denormalised blocks inserted with transforms applied
console.log(`denormalised: ${helper.denormalised.length} entities.\n`)
// Group entities by layer. Returns an object with layer names as
// keys to arrays of entities.
const groups = helper.groups
console.log('grouped entities')
console.log('----------------')
Object.keys(groups).forEach(layer => {
console.log(`${layer}: ${groups[layer].length}`)
})
console.log('\n')
// Write the SVG
const svg = helper.toSVG()
fs.writeFileSync(join(__dirname, '/example.es5.svg'), svg, 'utf-8')
console.log('SVG written')

View File

@ -0,0 +1,29 @@
import fs from 'fs'
import { join } from 'path'
import { Helper } from '../src'
const helper = new Helper(fs.readFileSync(
'./test/resources/Ceco.NET-Architecture-Tm-53.dxf', 'utf-8'))
// The parsed entities
const { blocks, entities } = helper.parsed
console.log(`parsed: ${blocks.length} blocks, ${entities.length} entities.\n`)
// Denormalised blocks inserted with transforms applied
console.log(`denormalised: ${helper.denormalised.length} entities.\n`)
// Group entities by layer. Returns an object with layer names as
// keys to arrays of entities.
const groups = helper.groups
console.log('grouped entities')
console.log('----------------')
Object.keys(groups).forEach(layer => {
console.log(`${layer}: ${groups[layer].length}`)
})
console.log('\n')
// Write the SVG
const svg = helper.toSVG()
fs.writeFileSync(join(__dirname, '/example.es6.svg'), svg, 'utf-8')
console.log('SVG written')

View File

@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _logger = _interopRequireDefault(require("./util/logger"));
var _parseString = _interopRequireDefault(require("./parseString"));
var _denormalise2 = _interopRequireDefault(require("./denormalise"));
var _toSVG2 = _interopRequireDefault(require("./toSVG"));
var _toPolylines2 = _interopRequireDefault(require("./toPolylines"));
var _groupEntitiesByLayer = _interopRequireDefault(require("./groupEntitiesByLayer"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Helper = /*#__PURE__*/function () {
function Helper(contents) {
_classCallCheck(this, Helper);
if (!(typeof contents === 'string')) {
throw Error('Helper constructor expects a DXF string');
}
this._contents = contents;
this._parsed = null;
this._denormalised = null;
}
_createClass(Helper, [{
key: "parse",
value: function parse() {
this._parsed = (0, _parseString["default"])(this._contents);
_logger["default"].info('parsed:', this.parsed);
return this._parsed;
}
}, {
key: "denormalise",
value: function denormalise() {
this._denormalised = (0, _denormalise2["default"])(this.parsed);
_logger["default"].info('denormalised:', this._denormalised);
return this._denormalised;
}
}, {
key: "group",
value: function group() {
this._groups = (0, _groupEntitiesByLayer["default"])(this.denormalised);
}
}, {
key: "toSVG",
value: function toSVG() {
return (0, _toSVG2["default"])(this.parsed);
}
}, {
key: "toPolylines",
value: function toPolylines() {
return (0, _toPolylines2["default"])(this.parsed);
}
}, {
key: "parsed",
get: function get() {
if (this._parsed === null) {
this.parse();
}
return this._parsed;
}
}, {
key: "denormalised",
get: function get() {
if (!this._denormalised) {
this.denormalise();
}
return this._denormalised;
}
}, {
key: "groups",
get: function get() {
if (!this._groups) {
this.group();
}
return this._groups;
}
}]);
return Helper;
}();
exports["default"] = Helper;

View File

@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**
* Apply the transforms to the polyline.
*
* @param polyline the polyline
* @param transform the transforms array
* @returns the transformed polyline
*/
var _default = function _default(polyline, transforms) {
transforms.forEach(function (transform) {
polyline = polyline.map(function (p) {
// Use a copy to avoid side effects
var p2 = [p[0], p[1]];
if (transform.scaleX) {
p2[0] = p2[0] * transform.scaleX;
}
if (transform.scaleY) {
p2[1] = p2[1] * transform.scaleY;
}
if (transform.rotation) {
var angle = transform.rotation / 180 * Math.PI;
p2 = [p2[0] * Math.cos(angle) - p2[1] * Math.sin(angle), p2[1] * Math.cos(angle) + p2[0] * Math.sin(angle)];
}
if (transform.x) {
p2[0] = p2[0] + transform.x;
}
if (transform.y) {
p2[1] = p2[1] + transform.y;
} // Observed once in a sample DXF - some cad applications
// use negative extruxion Z for flipping
if (transform.extrusionZ === -1) {
p2[0] = -p2[0];
}
return p2;
});
});
return polyline;
};
exports["default"] = _default;

View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
"use strict";
var _commander = _interopRequireDefault(require("commander"));
var _fs = _interopRequireDefault(require("fs"));
var _ = require("./");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
_commander["default"].version(require('../package.json').version).description('Converts a dxf file to a svg file.').arguments('<dxfFile> [svgFile]').option('-v --verbose', 'Verbose output').action(function (dxfFile, svgFile, options) {
var parsed = (0, _.parseString)(_fs["default"].readFileSync(dxfFile, 'utf-8'));
if (options.verbose) {
var groups = (0, _.groupEntitiesByLayer)((0, _.denormalise)(parsed));
console.log('[layer : number of entities]');
Object.keys(groups).forEach(function (layer) {
console.log("".concat(layer, " : ").concat(groups[layer].length));
});
}
_fs["default"].writeFileSync(svgFile || "".concat(dxfFile.split('.').slice(0, -1).join('.'), ".svg"), (0, _.toSVG)(parsed), 'utf-8');
}).parse(process.argv);
if (!process.argv.slice(2).length) {
_commander["default"].help();
}

View File

@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = {
verbose: false
};
exports["default"] = _default;

View File

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ZERO_TRANSFORM = void 0;
var ZERO_TRANSFORM = {
x: 0,
y: 0,
xScale: 1,
yScale: 1,
rotation: 0
};
exports.ZERO_TRANSFORM = ZERO_TRANSFORM;

View File

@ -0,0 +1,160 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _lodash = require("lodash");
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var _default = function _default(parseResult) {
var blocksByName = parseResult.blocks.reduce(function (acc, b) {
acc[b.name] = b;
return acc;
}, {});
var gatherEntities = function gatherEntities(entities, transforms) {
var current = [];
entities.forEach(function (e) {
if (e.type === 'INSERT') {
var _ret = function () {
var _insert$rowCount, _insert$columnCount, _insert$rowSpacing, _insert$columnSpacing, _insert$rotation;
var insert = e;
var block = blocksByName[insert.block];
if (!block) {
_logger["default"].error('no block found for insert. block:', insert.block);
return {
v: void 0
};
}
var rowCount = (_insert$rowCount = insert.rowCount) !== null && _insert$rowCount !== void 0 ? _insert$rowCount : 1;
var columnCount = (_insert$columnCount = insert.columnCount) !== null && _insert$columnCount !== void 0 ? _insert$columnCount : 1;
var rowSpacing = (_insert$rowSpacing = insert.rowSpacing) !== null && _insert$rowSpacing !== void 0 ? _insert$rowSpacing : 0;
var columnSpacing = (_insert$columnSpacing = insert.columnSpacing) !== null && _insert$columnSpacing !== void 0 ? _insert$columnSpacing : 0;
var rotation = (_insert$rotation = insert.rotation) !== null && _insert$rotation !== void 0 ? _insert$rotation : 0; // It appears that the rectangular array is affected by rotation, but NOT by scale.
var rowVec, colVec;
if (rowCount > 1 || columnCount > 1) {
var cos = Math.cos(rotation * Math.PI / 180);
var sin = Math.sin(rotation * Math.PI / 180);
rowVec = {
x: -sin * rowSpacing,
y: cos * rowSpacing
};
colVec = {
x: cos * columnSpacing,
y: sin * columnSpacing
};
} else {
rowVec = {
x: 0,
y: 0
};
colVec = {
x: 0,
y: 0
};
} // For rectangular arrays, add the block entities for each location in the array
for (var r = 0; r < rowCount; r++) {
for (var c = 0; c < columnCount; c++) {
// Adjust insert transform by row and column for rectangular arrays
var t = {
x: insert.x + rowVec.x * r + colVec.x * c,
y: insert.y + rowVec.y * r + colVec.y * c,
scaleX: insert.scaleX,
scaleY: insert.scaleY,
scaleZ: insert.scaleZ,
extrusionX: insert.extrusionX,
extrusionY: insert.extrusionY,
extrusionZ: insert.extrusionZ,
rotation: insert.rotation
}; // Add the insert transform and recursively add entities
var transforms2 = transforms.slice(0);
transforms2.push(t); // Use the insert layer
var blockEntities = block.entities.map(function (be) {
var be2 = (0, _lodash.cloneDeep)(be);
be2.layer = insert.layer; // https://github.com/bjnortier/dxf/issues/52
// See Issue 52. If we don't modify the
// entity coordinates here it creates an issue with the
// transformation matrices (which are only applied AFTER
// block insertion modifications has been applied).
switch (be2.type) {
case 'LINE':
{
be2.start.x -= block.x;
be2.start.y -= block.y;
be2.end.x -= block.x;
be2.end.y -= block.y;
break;
}
case 'LWPOLYLINE':
case 'POLYLINE':
{
be2.vertices.forEach(function (v) {
v.x -= block.x;
v.y -= block.y;
});
break;
}
case 'CIRCLE':
case 'ELLIPSE':
case 'ARC':
{
be2.x -= block.x;
be2.y -= block.y;
break;
}
case 'SPLINE':
{
be2.controlPoints.forEach(function (cp) {
cp.x -= block.x;
cp.y -= block.y;
});
break;
}
}
return be2;
});
current = current.concat(gatherEntities(blockEntities, transforms2));
}
}
}();
if (_typeof(_ret) === "object") return _ret.v;
} else {
// Top-level entity. Clone and add the transforms
// The transforms are reversed so they occur in
// order of application - i.e. the transform of the
// top-level insert is applied last
var e2 = (0, _lodash.cloneDeep)(e);
e2.transforms = transforms.slice().reverse();
current.push(e2);
}
});
return current;
};
return gatherEntities(parseResult.entities, []);
};
exports["default"] = _default;

View File

@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.interpolateBSpline = void 0;
var _bSpline = _interopRequireDefault(require("./util/bSpline"));
var _logger = _interopRequireDefault(require("./util/logger"));
var _createArcForLWPolyline = _interopRequireDefault(require("./util/createArcForLWPolyline"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* Rotate a set of points.
*
* @param points the points
* @param angle the rotation angle
*/
var rotate = function rotate(points, angle) {
return points.map(function (p) {
return [p[0] * Math.cos(angle) - p[1] * Math.sin(angle), p[1] * Math.cos(angle) + p[0] * Math.sin(angle)];
});
};
/**
* Interpolate an ellipse
* @param cx center X
* @param cy center Y
* @param rx radius X
* @param ry radius Y
* @param start start angle in radians
* @param start end angle in radians
*/
var interpolateEllipse = function interpolateEllipse(cx, cy, rx, ry, start, end, rotationAngle) {
if (end < start) {
end += Math.PI * 2;
} // ----- Relative points -----
// Start point
var points = [];
var dTheta = Math.PI * 2 / 72;
var EPS = 1e-6;
for (var theta = start; theta < end - EPS; theta += dTheta) {
points.push([Math.cos(theta) * rx, Math.sin(theta) * ry]);
}
points.push([Math.cos(end) * rx, Math.sin(end) * ry]); // ----- Rotate -----
if (rotationAngle) {
points = rotate(points, rotationAngle);
} // ----- Offset center -----
points = points.map(function (p) {
return [cx + p[0], cy + p[1]];
});
return points;
};
/**
* Interpolate a b-spline. The algorithm examins the knot vector
* to create segments for interpolation. The parameterisation value
* is re-normalised back to [0,1] as that is what the lib expects (
* and t i de-normalised in the b-spline library)
*
* @param controlPoints the control points
* @param degree the b-spline degree
* @param knots the knot vector
* @returns the polyline
*/
var interpolateBSpline = function interpolateBSpline(controlPoints, degree, knots, interpolationsPerSplineSegment) {
var polyline = [];
var controlPointsForLib = controlPoints.map(function (p) {
return [p.x, p.y];
});
var segmentTs = [knots[degree]];
var domain = [knots[degree], knots[knots.length - 1 - degree]];
for (var k = degree + 1; k < knots.length - degree; ++k) {
if (segmentTs[segmentTs.length - 1] !== knots[k]) {
segmentTs.push(knots[k]);
}
}
interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25;
for (var i = 1; i < segmentTs.length; ++i) {
var uMin = segmentTs[i - 1];
var uMax = segmentTs[i];
for (var _k = 0; _k <= interpolationsPerSplineSegment; ++_k) {
var u = _k / interpolationsPerSplineSegment * (uMax - uMin) + uMin; // Clamp t to 0, 1 to handle numerical precision issues
var t = (u - domain[0]) / (domain[1] - domain[0]);
t = Math.max(t, 0);
t = Math.min(t, 1);
var p = (0, _bSpline["default"])(t, degree, controlPointsForLib, knots);
polyline.push(p);
}
}
return polyline;
};
/**
* Convert a parsed DXF entity to a polyline. These can be used to render the
* the DXF in SVG, Canvas, WebGL etc., without depending on native support
* of primitive objects (ellispe, spline etc.)
*/
exports.interpolateBSpline = interpolateBSpline;
var _default = function _default(entity, options) {
options = options || {};
var polyline;
if (entity.type === 'LINE') {
polyline = [[entity.start.x, entity.start.y], [entity.end.x, entity.end.y]];
}
if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {
polyline = [];
if (entity.polygonMesh || entity.polyfaceMesh) {// Do not attempt to render meshes
} else if (entity.vertices.length) {
if (entity.closed) {
entity.vertices = entity.vertices.concat(entity.vertices[0]);
}
for (var i = 0, il = entity.vertices.length; i < il - 1; ++i) {
var from = [entity.vertices[i].x, entity.vertices[i].y];
var to = [entity.vertices[i + 1].x, entity.vertices[i + 1].y];
polyline.push(from);
if (entity.vertices[i].bulge) {
polyline = polyline.concat((0, _createArcForLWPolyline["default"])(from, to, entity.vertices[i].bulge));
} // The last iteration of the for loop
if (i === il - 2) {
polyline.push(to);
}
}
} else {
_logger["default"].warn('Polyline entity with no vertices');
}
}
if (entity.type === 'CIRCLE') {
polyline = interpolateEllipse(entity.x, entity.y, entity.r, entity.r, 0, Math.PI * 2);
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'ELLIPSE') {
var rx = Math.sqrt(entity.majorX * entity.majorX + entity.majorY * entity.majorY);
var ry = entity.axisRatio * rx;
var majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX);
polyline = interpolateEllipse(entity.x, entity.y, rx, ry, entity.startAngle, entity.endAngle, majorAxisRotation);
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'ARC') {
// Why on earth DXF has degree start & end angles for arc,
// and radian start & end angles for ellipses is a mystery
polyline = interpolateEllipse(entity.x, entity.y, entity.r, entity.r, entity.startAngle, entity.endAngle, undefined, false); // I kid you not, ARCs and ELLIPSEs handle this differently,
// as evidenced by how AutoCAD actually renders these entities
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'SPLINE') {
polyline = interpolateBSpline(entity.controlPoints, entity.degree, entity.knots, options.interpolationsPerSplineSegment);
}
if (!polyline) {
_logger["default"].warn('unsupported entity for converting to polyline:', entity.type);
return [];
}
return polyline;
};
exports["default"] = _default;

View File

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _colors = _interopRequireDefault(require("./util/colors"));
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var _default = function _default(layers, entity) {
var layerTable = layers[entity.layer];
if (layerTable) {
var colorNumber = 'colorNumber' in entity ? entity.colorNumber : layerTable.colorNumber;
var rgb = _colors["default"][colorNumber];
if (rgb) {
return rgb;
} else {
_logger["default"].warn('Color index', colorNumber, 'invalid, defaulting to black');
return [0, 0, 0];
}
} else {
_logger["default"].warn('no layer table for layer:' + entity.layer);
return [0, 0, 0];
}
};
exports["default"] = _default;

View File

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = function _default(entities) {
return entities.reduce(function (acc, entity) {
var layer = entity.layer;
if (!acc[layer]) {
acc[layer] = [];
}
acc[layer].push(entity);
return acc;
}, {});
};
exports["default"] = _default;

View File

@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _entities = _interopRequireDefault(require("./entities"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var _default = function _default(tuples) {
var state;
var blocks = [];
var block;
var entitiesTuples = [];
tuples.forEach(function (tuple) {
var type = tuple[0];
var value = tuple[1];
if (value === 'BLOCK') {
state = 'block';
block = {};
entitiesTuples = [];
blocks.push(block);
} else if (value === 'ENDBLK') {
if (state === 'entities') {
block.entities = (0, _entities["default"])(entitiesTuples);
} else {
block.entities = [];
}
entitiesTuples = undefined;
state = undefined;
} else if (state === 'block' && type !== 0) {
switch (type) {
case 1:
block.xref = value;
break;
case 2:
block.name = value;
break;
case 10:
block.x = value;
break;
case 20:
block.y = value;
break;
case 30:
block.z = value;
break;
default:
break;
}
} else if (state === 'block' && type === 0) {
state = 'entities';
entitiesTuples.push(tuple);
} else if (state === 'entities') {
entitiesTuples.push(tuple);
}
});
return blocks;
};
exports["default"] = _default;

View File

@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _logger = _interopRequireDefault(require("../util/logger"));
var _point = _interopRequireDefault(require("./entity/point"));
var _line = _interopRequireDefault(require("./entity/line"));
var _lwpolyline = _interopRequireDefault(require("./entity/lwpolyline"));
var _polyline = _interopRequireDefault(require("./entity/polyline"));
var _vertex = _interopRequireDefault(require("./entity/vertex"));
var _circle = _interopRequireDefault(require("./entity/circle"));
var _arc = _interopRequireDefault(require("./entity/arc"));
var _ellipse = _interopRequireDefault(require("./entity/ellipse"));
var _spline = _interopRequireDefault(require("./entity/spline"));
var _solid = _interopRequireDefault(require("./entity/solid"));
var _mtext = _interopRequireDefault(require("./entity/mtext"));
var _insert = _interopRequireDefault(require("./entity/insert"));
var _threeDFace = _interopRequireDefault(require("./entity/threeDFace"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var handlers = [_point["default"], _line["default"], _lwpolyline["default"], _polyline["default"], _vertex["default"], _circle["default"], _arc["default"], _ellipse["default"], _spline["default"], _solid["default"], _mtext["default"], _insert["default"], _threeDFace["default"]].reduce(function (acc, mod) {
acc[mod.TYPE] = mod;
return acc;
}, {});
var _default = function _default(tuples) {
var entities = [];
var entityGroups = [];
var currentEntityTuples; // First group them together for easy processing
tuples.forEach(function (tuple) {
var type = tuple[0];
if (type === 0) {
currentEntityTuples = [];
entityGroups.push(currentEntityTuples);
}
currentEntityTuples.push(tuple);
});
var currentPolyline;
entityGroups.forEach(function (tuples) {
var entityType = tuples[0][1];
var contentTuples = tuples.slice(1);
if (handlers[entityType] !== undefined) {
var e = handlers[entityType].process(contentTuples); // "POLYLINE" cannot be parsed in isolation, it is followed by
// N "VERTEX" entities and ended with a "SEQEND" entity.
// Essentially we convert POLYLINE to LWPOLYLINE - the extra
// vertex flags are not supported
if (entityType === 'POLYLINE') {
currentPolyline = e;
entities.push(e);
} else if (entityType === 'VERTEX') {
if (currentPolyline) {
currentPolyline.vertices.push(e);
} else {
_logger["default"].error('ignoring invalid VERTEX entity');
}
} else if (entityType === 'SEQEND') {
currentPolyline = undefined;
} else {
// All other entities
entities.push(e);
}
} else {
_logger["default"].warn('unsupported type in ENTITIES section:', entityType);
}
});
return entities;
};
exports["default"] = _default;

View File

@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'ARC';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 39:
entity.thickness = value;
break;
case 40:
entity.r = value;
break;
case 50:
// *Someone* decided that ELLIPSE angles are in radians but
// ARC angles are in degrees
entity.startAngle = value / 180 * Math.PI;
break;
case 51:
entity.endAngle = value / 180 * Math.PI;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'CIRCLE';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 40:
entity.r = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = function _default(type, value) {
switch (type) {
case 6:
// Linetype name (present if not BYLAYER).
// The special name BYBLOCK indicates a
// floating linetype. (optional)
return {
lineTypeName: value
};
case 8:
return {
layer: value
};
case 48:
// Linetype scale (optional)
return {
lineTypeScale: value
};
case 60:
// Object visibility (optional): 0 = visible, 1 = invisible.
return {
visible: value === 0
};
case 62:
// Color number (present if not BYLAYER).
// Zero indicates the BYBLOCK (floating) color.
// 256 indicates BYLAYER.
// A negative value indicates that the layer is turned off. (optional)
return {
colorNumber: value
};
case 210:
return {
extrusionX: value
};
case 220:
return {
extrusionY: value
};
case 230:
return {
extrusionZ: value
};
default:
return {};
}
};
exports["default"] = _default;

View File

@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'ELLIPSE';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 11:
entity.majorX = value;
break;
case 20:
entity.y = value;
break;
case 21:
entity.majorY = value;
break;
case 30:
entity.z = value;
break;
case 31:
entity.majorZ = value;
break;
case 40:
entity.axisRatio = value;
break;
case 41:
entity.startAngle = value;
break;
case 42:
entity.endAngle = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'INSERT';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 2:
entity.block = value;
break;
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 41:
entity.scaleX = value;
break;
case 42:
entity.scaleY = value;
break;
case 43:
entity.scaleZ = value;
break;
case 44:
entity.columnSpacing = value;
break;
case 45:
entity.rowSpacing = value;
break;
case 50:
entity.rotation = value;
break;
case 70:
entity.columnCount = value;
break;
case 71:
entity.rowCount = value;
break;
case 210:
entity.extrusionX = value;
break;
case 220:
entity.extrusionY = value;
break;
case 230:
entity.extrusionZ = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'LINE';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.start.x = value;
break;
case 20:
entity.start.y = value;
break;
case 30:
entity.start.z = value;
break;
case 39:
entity.thickness = value;
break;
case 11:
entity.end.x = value;
break;
case 21:
entity.end.y = value;
break;
case 31:
entity.end.z = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
start: {},
end: {}
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'LWPOLYLINE';
exports.TYPE = TYPE;
var process = function process(tuples) {
var vertex;
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 70:
entity.closed = (value & 1) === 1;
break;
case 10:
vertex = {
x: value,
y: 0
};
entity.vertices.push(vertex);
break;
case 20:
vertex.y = value;
break;
case 39:
entity.thickness = value;
break;
case 42:
// Bulge (multiple entries; one entry for each vertex) (optional; default = 0).
vertex.bulge = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
vertices: []
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'MTEXT';
exports.TYPE = TYPE;
var simpleCodes = {
10: 'x',
20: 'y',
30: 'z',
40: 'nominalTextHeight',
41: 'refRectangleWidth',
71: 'attachmentPoint',
72: 'drawingDirection',
7: 'styleName',
11: 'xAxisX',
21: 'xAxisY',
31: 'xAxisZ',
42: 'horizontalWidth',
43: 'verticalHeight',
73: 'lineSpacingStyle',
44: 'lineSpacingFactor',
90: 'backgroundFill',
420: 'bgColorRGB0',
421: 'bgColorRGB1',
422: 'bgColorRGB2',
423: 'bgColorRGB3',
424: 'bgColorRGB4',
425: 'bgColorRGB5',
426: 'bgColorRGB6',
427: 'bgColorRGB7',
428: 'bgColorRGB8',
429: 'bgColorRGB9',
430: 'bgColorName0',
431: 'bgColorName1',
432: 'bgColorName2',
433: 'bgColorName3',
434: 'bgColorName4',
435: 'bgColorName5',
436: 'bgColorName6',
437: 'bgColorName7',
438: 'bgColorName8',
439: 'bgColorName9',
45: 'fillBoxStyle',
63: 'bgFillColor',
441: 'bgFillTransparency',
75: 'columnType',
76: 'columnCount',
78: 'columnFlowReversed',
79: 'columnAutoheight',
48: 'columnWidth',
49: 'columnGutter',
50: 'columnHeights'
};
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
if (simpleCodes[type] !== undefined) {
entity[simpleCodes[type]] = value;
} else if (type === 1 || type === 3) {
entity.string += value;
} else if (type === 50) {
// Rotation angle in radians
entity.xAxisX = Math.cos(value);
entity.xAxisY = Math.sin(value);
} else {
Object.assign(entity, (0, _common["default"])(type, value));
}
return entity;
}, {
type: TYPE,
string: ''
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'POINT';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 39:
entity.thickness = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'POLYLINE';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 70:
entity.closed = (value & 1) === 1;
entity.polygonMesh = (value & 16) === 16;
entity.polyfaceMesh = (value & 64) === 64;
break;
case 39:
entity.thickness = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
vertices: []
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,90 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'SOLID';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.corners[0].x = value;
break;
case 20:
entity.corners[0].y = value;
break;
case 30:
entity.corners[0].z = value;
break;
case 11:
entity.corners[1].x = value;
break;
case 21:
entity.corners[1].y = value;
break;
case 31:
entity.corners[1].z = value;
break;
case 12:
entity.corners[2].x = value;
break;
case 22:
entity.corners[2].y = value;
break;
case 32:
entity.corners[2].z = value;
break;
case 13:
entity.corners[3].x = value;
break;
case 23:
entity.corners[3].y = value;
break;
case 33:
entity.corners[3].z = value;
break;
case 39:
entity.thickness = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
corners: [{}, {}, {}, {}]
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = 'SPLINE';
exports.TYPE = TYPE;
var process = function process(tuples) {
var controlPoint;
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
controlPoint = {
x: value,
y: 0
};
entity.controlPoints.push(controlPoint);
break;
case 20:
controlPoint.y = value;
break;
case 30:
controlPoint.z = value;
break;
case 40:
entity.knots.push(value);
break;
case 42:
entity.knotTolerance = value;
break;
case 43:
entity.controlPointTolerance = value;
break;
case 44:
entity.fitTolerance = value;
break;
case 70:
// Spline flag (bit coded):
// 1 = Closed spline
// 2 = Periodic spline
// 4 = Rational spline
// 8 = Planar
// 16 = Linear (planar bit is also set)
entity.flag = value;
entity.closed = (value & 1) === 1;
break;
case 71:
entity.degree = value;
break;
case 72:
entity.numberOfKnots = value;
break;
case 73:
entity.numberOfControlPoints = value;
break;
case 74:
entity.numberOfFitPoints = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
controlPoints: [],
knots: []
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,86 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var TYPE = '3DFACE';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.vertices[0].x = value;
break;
case 20:
entity.vertices[0].y = value;
break;
case 30:
entity.vertices[0].z = value;
break;
case 11:
entity.vertices[1].x = value;
break;
case 21:
entity.vertices[1].y = value;
break;
case 31:
entity.vertices[1].z = value;
break;
case 12:
entity.vertices[2].x = value;
break;
case 22:
entity.vertices[2].y = value;
break;
case 32:
entity.vertices[2].z = value;
break;
case 13:
entity.vertices[3].x = value;
break;
case 23:
entity.vertices[3].y = value;
break;
case 33:
entity.vertices[3].z = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
vertices: [{}, {}, {}, {}]
});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.process = exports.TYPE = void 0;
var TYPE = 'VERTEX';
exports.TYPE = TYPE;
var process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 42:
entity.bulge = value;
break;
default:
break;
}
return entity;
}, {});
};
exports.process = process;
var _default = {
TYPE: TYPE,
process: process
};
exports["default"] = _default;

View File

@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = function _default(tuples) {
var state;
var header = {};
tuples.forEach(function (tuple) {
var type = tuple[0];
var value = tuple[1];
switch (value) {
case '$MEASUREMENT':
{
state = 'measurement';
break;
}
case '$INSUNITS':
{
state = 'insUnits';
break;
}
case '$EXTMIN':
header.extMin = {};
state = 'extMin';
break;
case '$EXTMAX':
header.extMax = {};
state = 'extMax';
break;
default:
switch (state) {
case 'extMin':
case 'extMax':
{
switch (type) {
case 10:
header[state].x = value;
break;
case 20:
header[state].y = value;
break;
case 30:
header[state].z = value;
state = undefined;
break;
}
break;
}
case 'measurement':
case 'insUnits':
{
switch (type) {
case 70:
{
header[state] = value;
state = undefined;
break;
}
}
break;
}
}
}
});
return header;
};
exports["default"] = _default;

View File

@ -0,0 +1,162 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _logger = _interopRequireDefault(require("../util/logger"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var layerHandler = function layerHandler(tuples) {
return tuples.reduce(function (layer, tuple) {
var type = tuple[0];
var value = tuple[1]; // https://www.autodesk.com/techpubs/autocad/acad2000/dxf/layer_dxf_04.htm
switch (type) {
case 2:
layer.name = value;
break;
case 6:
layer.lineTypeName = value;
break;
case 62:
layer.colorNumber = value;
break;
case 70:
layer.flags = value;
break;
case 290:
layer.plot = parseInt(value) !== 0;
break;
case 370:
layer.lineWeightEnum = value;
break;
default:
}
return layer;
}, {
type: 'LAYER'
});
};
var styleHandler = function styleHandler(tuples) {
return tuples.reduce(function (style, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 2:
style.name = value;
break;
case 6:
style.lineTypeName = value;
break;
case 40:
style.fixedTextHeight = value;
break;
case 41:
style.widthFactor = value;
break;
case 50:
style.obliqueAngle = value;
break;
case 71:
style.flags = value;
break;
case 42:
style.lastHeightUsed = value;
break;
case 3:
style.primaryFontFileName = value;
break;
case 4:
style.bigFontFileName = value;
break;
default:
}
return style;
}, {
type: 'STYLE'
});
};
var tableHandler = function tableHandler(tuples, tableType, handler) {
var tableRowsTuples = [];
var tableRowTuples;
tuples.forEach(function (tuple) {
var type = tuple[0];
var value = tuple[1];
if ((type === 0 || type === 2) && value === tableType) {
tableRowTuples = [];
tableRowsTuples.push(tableRowTuples);
} else {
tableRowTuples.push(tuple);
}
});
return tableRowsTuples.reduce(function (acc, rowTuples) {
var tableRow = handler(rowTuples);
if (tableRow.name) {
acc[tableRow.name] = tableRow;
} else {
_logger["default"].warn('table row without name:', tableRow);
}
return acc;
}, {});
};
var _default = function _default(tuples) {
var tableGroups = [];
var tableTuples;
tuples.forEach(function (tuple) {
// const type = tuple[0];
var value = tuple[1];
if (value === 'TABLE') {
tableTuples = [];
tableGroups.push(tableTuples);
} else if (value === 'ENDTAB') {
tableGroups.push(tableTuples);
} else {
tableTuples.push(tuple);
}
});
var stylesTuples = [];
var layersTuples = [];
tableGroups.forEach(function (group) {
if (group[0][1] === 'STYLE') {
stylesTuples = group;
} else if (group[0][1] === 'LTYPE') {
_logger["default"].warn('LTYPE in tables not supported');
} else if (group[0][1] === 'LAYER') {
layersTuples = group;
}
});
return {
layers: tableHandler(layersTuples, 'LAYER', layerHandler),
styles: tableHandler(stylesTuples, 'STYLE', styleHandler)
};
};
exports["default"] = _default;

View File

@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "config", {
enumerable: true,
get: function get() {
return _config["default"];
}
});
Object.defineProperty(exports, "parseString", {
enumerable: true,
get: function get() {
return _parseString["default"];
}
});
Object.defineProperty(exports, "denormalise", {
enumerable: true,
get: function get() {
return _denormalise["default"];
}
});
Object.defineProperty(exports, "groupEntitiesByLayer", {
enumerable: true,
get: function get() {
return _groupEntitiesByLayer["default"];
}
});
Object.defineProperty(exports, "toPolylines", {
enumerable: true,
get: function get() {
return _toPolylines["default"];
}
});
Object.defineProperty(exports, "toSVG", {
enumerable: true,
get: function get() {
return _toSVG["default"];
}
});
Object.defineProperty(exports, "colors", {
enumerable: true,
get: function get() {
return _colors["default"];
}
});
Object.defineProperty(exports, "Helper", {
enumerable: true,
get: function get() {
return _Helper["default"];
}
});
var _config = _interopRequireDefault(require("./config"));
var _parseString = _interopRequireDefault(require("./parseString"));
var _denormalise = _interopRequireDefault(require("./denormalise"));
var _groupEntitiesByLayer = _interopRequireDefault(require("./groupEntitiesByLayer"));
var _toPolylines = _interopRequireDefault(require("./toPolylines"));
var _toSVG = _interopRequireDefault(require("./toSVG"));
var _colors = _interopRequireDefault(require("./util/colors"));
var _Helper = _interopRequireDefault(require("./Helper"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

View File

@ -0,0 +1,133 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _header = _interopRequireDefault(require("./handlers/header"));
var _tables = _interopRequireDefault(require("./handlers/tables"));
var _blocks = _interopRequireDefault(require("./handlers/blocks"));
var _entities = _interopRequireDefault(require("./handlers/entities"));
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { 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 = o[Symbol.iterator](); }, 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; }
// Parse the value into the native representation
var parseValue = function parseValue(type, value) {
if (type >= 10 && type < 60) {
return parseFloat(value, 10);
} else if (type >= 210 && type < 240) {
return parseFloat(value, 10);
} else if (type >= 60 && type < 100) {
return parseInt(value, 10);
} else {
return value;
}
}; // Content lines are alternate lines of type and value
var convertToTypesAndValues = function convertToTypesAndValues(contentLines) {
var state = 'type';
var type;
var typesAndValues = [];
var _iterator = _createForOfIteratorHelper(contentLines),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var line = _step.value;
if (state === 'type') {
type = parseInt(line, 10);
state = 'value';
} else {
typesAndValues.push([type, parseValue(type, line)]);
state = 'type';
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return typesAndValues;
};
var separateSections = function separateSections(tuples) {
var sectionTuples;
return tuples.reduce(function (sections, tuple) {
if (tuple[0] === 0 && tuple[1] === 'SECTION') {
sectionTuples = [];
} else if (tuple[0] === 0 && tuple[1] === 'ENDSEC') {
sections.push(sectionTuples);
sectionTuples = undefined;
} else if (sectionTuples !== undefined) {
sectionTuples.push(tuple);
}
return sections;
}, []);
}; // Each section start with the type tuple, then proceeds
// with the contents of the section
var reduceSection = function reduceSection(acc, section) {
var sectionType = section[0][1];
var contentTuples = section.slice(1);
switch (sectionType) {
case 'HEADER':
acc.header = (0, _header["default"])(contentTuples);
break;
case 'TABLES':
acc.tables = (0, _tables["default"])(contentTuples);
break;
case 'BLOCKS':
acc.blocks = (0, _blocks["default"])(contentTuples);
break;
case 'ENTITIES':
acc.entities = (0, _entities["default"])(contentTuples);
break;
default:
_logger["default"].warn("Unsupported section: ".concat(sectionType));
}
return acc;
};
var _default = function _default(string) {
var lines = string.split(/\r\n|\r|\n/g);
var tuples = convertToTypesAndValues(lines);
var sections = separateSections(tuples);
var result = sections.reduce(reduceSection, {
// Start with empty defaults in the event of empty sections
header: {},
blocks: [],
entities: [],
tables: {
layers: {},
styles: {}
}
});
return result;
};
exports["default"] = _default;

View File

@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _vecks = require("vecks");
var _colors = _interopRequireDefault(require("./util/colors"));
var _denormalise = _interopRequireDefault(require("./denormalise"));
var _entityToPolyline = _interopRequireDefault(require("./entityToPolyline"));
var _applyTransforms = _interopRequireDefault(require("./applyTransforms"));
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var _default = function _default(parsed) {
var entities = (0, _denormalise["default"])(parsed);
var polylines = entities.map(function (entity) {
var layerTable = parsed.tables.layers[entity.layer];
var rgb;
if (layerTable) {
var colorNumber = 'colorNumber' in entity ? entity.colorNumber : layerTable.colorNumber;
rgb = _colors["default"][colorNumber];
if (rgb === undefined) {
_logger["default"].warn('Color index', colorNumber, 'invalid, defaulting to black');
rgb = [0, 0, 0];
}
} else {
_logger["default"].warn('no layer table for layer:' + entity.layer);
rgb = [0, 0, 0];
}
return {
rgb: rgb,
vertices: (0, _applyTransforms["default"])((0, _entityToPolyline["default"])(entity), entity.transforms)
};
});
var bbox = new _vecks.Box2();
polylines.forEach(function (polyline) {
polyline.vertices.forEach(function (vertex) {
bbox.expandByPoint({
x: vertex[0],
y: vertex[1]
});
});
});
return {
bbox: bbox,
polylines: polylines
};
};
exports["default"] = _default;

View File

@ -0,0 +1,401 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.piecewiseToPaths = void 0;
var _prettyData = require("pretty-data");
var _vecks = require("vecks");
var _entityToPolyline = _interopRequireDefault(require("./entityToPolyline"));
var _denormalise = _interopRequireDefault(require("./denormalise"));
var _getRGBForEntity = _interopRequireDefault(require("./getRGBForEntity"));
var _logger = _interopRequireDefault(require("./util/logger"));
var _rotate = _interopRequireDefault(require("./util/rotate"));
var _rgbToColorAttribute = _interopRequireDefault(require("./util/rgbToColorAttribute"));
var _toPiecewiseBezier = _interopRequireWildcard(require("./util/toPiecewiseBezier"));
var _transformBoundingBoxAndElement = _interopRequireDefault(require("./util/transformBoundingBoxAndElement"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var addFlipXIfApplicable = function addFlipXIfApplicable(entity, _ref) {
var bbox = _ref.bbox,
element = _ref.element;
if (entity.extrusionZ === -1) {
return {
bbox: new _vecks.Box2().expandByPoint({
x: -bbox.min.x,
y: bbox.min.y
}).expandByPoint({
x: -bbox.max.x,
y: bbox.max.y
}),
element: "<g transform=\"matrix(-1 0 0 1 0 0)\">\n ".concat(element, "\n </g>")
};
} else {
return {
bbox: bbox,
element: element
};
}
};
/**
* Create a <path /> element. Interpolates curved entities.
*/
var polyline = function polyline(entity) {
var vertices = (0, _entityToPolyline["default"])(entity);
var bbox = vertices.reduce(function (acc, _ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
x = _ref3[0],
y = _ref3[1];
return acc.expandByPoint({
x: x,
y: y
});
}, new _vecks.Box2());
var d = vertices.reduce(function (acc, point, i) {
acc += i === 0 ? 'M' : 'L';
acc += point[0] + ',' + point[1];
return acc;
}, ''); // Empirically it appears that flipping horzontally does not apply to polyline
return (0, _transformBoundingBoxAndElement["default"])(bbox, "<path d=\"".concat(d, "\" />"), entity.transforms);
};
/**
* Create a <circle /> element for the CIRCLE entity.
*/
var circle = function circle(entity) {
var bbox0 = new _vecks.Box2().expandByPoint({
x: entity.x + entity.r,
y: entity.y + entity.r
}).expandByPoint({
x: entity.x - entity.r,
y: entity.y - entity.r
});
var element0 = "<circle cx=\"".concat(entity.x, "\" cy=\"").concat(entity.y, "\" r=\"").concat(entity.r, "\" />");
var _addFlipXIfApplicable = addFlipXIfApplicable(entity, {
bbox: bbox0,
element: element0
}),
bbox = _addFlipXIfApplicable.bbox,
element = _addFlipXIfApplicable.element;
return (0, _transformBoundingBoxAndElement["default"])(bbox, element, entity.transforms);
};
/**
* Create a a <path d="A..." /> or <ellipse /> element for the ARC or ELLIPSE
* DXF entity (<ellipse /> if start and end point are the same).
*/
var ellipseOrArc = function ellipseOrArc(cx, cy, majorX, majorY, axisRatio, startAngle, endAngle, flipX) {
var rx = Math.sqrt(majorX * majorX + majorY * majorY);
var ry = axisRatio * rx;
var rotationAngle = -Math.atan2(-majorY, majorX);
var bbox = bboxEllipseOrArc(cx, cy, majorX, majorY, axisRatio, startAngle, endAngle, flipX);
if (Math.abs(startAngle - endAngle) < 1e-9 || Math.abs(startAngle - endAngle + Math.PI * 2) < 1e-9) {
// Use a native <ellipse> when start and end angles are the same, and
// arc paths with same start and end points don't render (at least on Safari)
var element = "<g transform=\"rotate(".concat(rotationAngle / Math.PI * 180, " ").concat(cx, ", ").concat(cy, ")\">\n <ellipse cx=\"").concat(cx, "\" cy=\"").concat(cy, "\" rx=\"").concat(rx, "\" ry=\"").concat(ry, "\" />\n </g>");
return {
bbox: bbox,
element: element
};
} else {
var startOffset = (0, _rotate["default"])({
x: Math.cos(startAngle) * rx,
y: Math.sin(startAngle) * ry
}, rotationAngle);
var startPoint = {
x: cx + startOffset.x,
y: cy + startOffset.y
};
var endOffset = (0, _rotate["default"])({
x: Math.cos(endAngle) * rx,
y: Math.sin(endAngle) * ry
}, rotationAngle);
var endPoint = {
x: cx + endOffset.x,
y: cy + endOffset.y
};
var adjustedEndAngle = endAngle < startAngle ? endAngle + Math.PI * 2 : endAngle;
var largeArcFlag = adjustedEndAngle - startAngle < Math.PI ? 0 : 1;
var d = "M ".concat(startPoint.x, " ").concat(startPoint.y, " A ").concat(rx, " ").concat(ry, " ").concat(rotationAngle / Math.PI * 180, " ").concat(largeArcFlag, " 1 ").concat(endPoint.x, " ").concat(endPoint.y);
var _element = "<path d=\"".concat(d, "\" />");
return {
bbox: bbox,
element: _element
};
}
};
/**
* Compute the bounding box of an elliptical arc, given the DXF entity parameters
*/
var bboxEllipseOrArc = function bboxEllipseOrArc(cx, cy, majorX, majorY, axisRatio, startAngle, endAngle, flipX) {
// The bounding box will be defined by the starting point of the ellipse, and ending point,
// and any extrema on the ellipse that are between startAngle and endAngle.
// The extrema are found by setting either the x or y component of the ellipse's
// tangent vector to zero and solving for the angle.
// Ensure start and end angles are > 0 and well-ordered
while (startAngle < 0) {
startAngle += Math.PI * 2;
}
while (endAngle <= startAngle) {
endAngle += Math.PI * 2;
} // When rotated, the extrema of the ellipse will be found at these angles
var angles = [];
if (Math.abs(majorX) < 1e-12 || Math.abs(majorY) < 1e-12) {
// Special case for majorX or majorY = 0
for (var i = 0; i < 4; i++) {
angles.push(i / 2 * Math.PI);
}
} else {
// reference https://github.com/bjnortier/dxf/issues/47#issuecomment-545915042
angles[0] = Math.atan(-majorY * axisRatio / majorX) - Math.PI; // Ensure angles < 0
angles[1] = Math.atan(majorX * axisRatio / majorY) - Math.PI;
angles[2] = angles[0] - Math.PI;
angles[3] = angles[1] - Math.PI;
} // Remove angles not falling between start and end
for (var _i2 = 4; _i2 >= 0; _i2--) {
while (angles[_i2] < startAngle) {
angles[_i2] += Math.PI * 2;
}
if (angles[_i2] > endAngle) {
angles.splice(_i2, 1);
}
} // Also to consider are the starting and ending points:
angles.push(startAngle);
angles.push(endAngle); // Compute points lying on the unit circle at these angles
var pts = angles.map(function (a) {
return {
x: Math.cos(a),
y: Math.sin(a)
};
}); // Transformation matrix, formed by the major and minor axes
var M = [[majorX, -majorY * axisRatio], [majorY, majorX * axisRatio]]; // Rotate, scale, and translate points
var rotatedPts = pts.map(function (p) {
return {
x: p.x * M[0][0] + p.y * M[0][1] + cx,
y: p.x * M[1][0] + p.y * M[1][1] + cy
};
}); // Compute extents of bounding box
var bbox = rotatedPts.reduce(function (acc, p) {
acc.expandByPoint(p);
return acc;
}, new _vecks.Box2());
return bbox;
};
/**
* An ELLIPSE is defined by the major axis, convert to X and Y radius with
* a rotation angle
*/
var ellipse = function ellipse(entity) {
var _ellipseOrArc = ellipseOrArc(entity.x, entity.y, entity.majorX, entity.majorY, entity.axisRatio, entity.startAngle, entity.endAngle),
bbox0 = _ellipseOrArc.bbox,
element0 = _ellipseOrArc.element;
var _addFlipXIfApplicable2 = addFlipXIfApplicable(entity, {
bbox: bbox0,
element: element0
}),
bbox = _addFlipXIfApplicable2.bbox,
element = _addFlipXIfApplicable2.element;
return (0, _transformBoundingBoxAndElement["default"])(bbox, element, entity.transforms);
};
/**
* An ARC is an ellipse with equal radii
*/
var arc = function arc(entity) {
var _ellipseOrArc2 = ellipseOrArc(entity.x, entity.y, entity.r, 0, 1, entity.startAngle, entity.endAngle, entity.extrusionZ === -1),
bbox0 = _ellipseOrArc2.bbox,
element0 = _ellipseOrArc2.element;
var _addFlipXIfApplicable3 = addFlipXIfApplicable(entity, {
bbox: bbox0,
element: element0
}),
bbox = _addFlipXIfApplicable3.bbox,
element = _addFlipXIfApplicable3.element;
return (0, _transformBoundingBoxAndElement["default"])(bbox, element, entity.transforms);
};
var piecewiseToPaths = function piecewiseToPaths(k, knots, controlPoints) {
var paths = [];
var controlPointIndex = 0;
var knotIndex = k;
while (knotIndex < knots.length - k + 1) {
var m = (0, _toPiecewiseBezier.multiplicity)(knots, knotIndex);
var cp = controlPoints.slice(controlPointIndex, controlPointIndex + k);
if (k === 4) {
paths.push("<path d=\"M ".concat(cp[0].x, " ").concat(cp[0].y, " C ").concat(cp[1].x, " ").concat(cp[1].y, " ").concat(cp[2].x, " ").concat(cp[2].y, " ").concat(cp[3].x, " ").concat(cp[3].y, "\" />"));
} else if (k === 3) {
paths.push("<path d=\"M ".concat(cp[0].x, " ").concat(cp[0].y, " Q ").concat(cp[1].x, " ").concat(cp[1].y, " ").concat(cp[2].x, " ").concat(cp[2].y, "\" />"));
}
controlPointIndex += m;
knotIndex += m;
}
return paths;
};
exports.piecewiseToPaths = piecewiseToPaths;
var bezier = function bezier(entity) {
var bbox = new _vecks.Box2();
entity.controlPoints.forEach(function (p) {
bbox = bbox.expandByPoint(p);
});
var k = entity.degree + 1;
var piecewise = (0, _toPiecewiseBezier["default"])(k, entity.controlPoints, entity.knots);
var paths = piecewiseToPaths(k, piecewise.knots, piecewise.controlPoints);
var element = "<g>".concat(paths.join(''), "</g>");
return (0, _transformBoundingBoxAndElement["default"])(bbox, element, entity.transforms);
};
/**
* Switcth the appropriate function on entity type. CIRCLE, ARC and ELLIPSE
* produce native SVG elements, the rest produce interpolated polylines.
*/
var entityToBoundsAndElement = function entityToBoundsAndElement(entity) {
switch (entity.type) {
case 'CIRCLE':
return circle(entity);
case 'ELLIPSE':
return ellipse(entity);
case 'ARC':
return arc(entity);
case 'SPLINE':
{
if (entity.degree === 2 || entity.degree === 3) {
try {
return bezier(entity);
} catch (err) {
return polyline(entity);
}
} else {
return polyline(entity);
}
}
case 'LINE':
case 'LWPOLYLINE':
case 'POLYLINE':
{
return polyline(entity);
}
default:
_logger["default"].warn('entity type not supported in SVG rendering:', entity.type);
return null;
}
};
var _default = function _default(parsed) {
var entities = (0, _denormalise["default"])(parsed);
var _entities$reduce = entities.reduce(function (acc, entity, i) {
var rgb = (0, _getRGBForEntity["default"])(parsed.tables.layers, entity);
var boundsAndElement = entityToBoundsAndElement(entity); // Ignore entities like MTEXT that don't produce SVG elements
if (boundsAndElement) {
var _bbox = boundsAndElement.bbox,
element = boundsAndElement.element; // Ignore invalid bounding boxes
if (_bbox.valid) {
acc.bbox.expandByPoint(_bbox.min);
acc.bbox.expandByPoint(_bbox.max);
}
acc.elements.push("<g stroke=\"".concat((0, _rgbToColorAttribute["default"])(rgb), "\">").concat(element, "</g>"));
}
return acc;
}, {
bbox: new _vecks.Box2(),
elements: []
}),
bbox = _entities$reduce.bbox,
elements = _entities$reduce.elements;
var viewBox = bbox.valid ? {
x: bbox.min.x,
y: -bbox.max.y,
width: bbox.max.x - bbox.min.x,
height: bbox.max.y - bbox.min.y
} : {
x: 0,
y: 0,
width: 0,
height: 0
};
return "<?xml version=\"1.0\"?>\n<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\"\n preserveAspectRatio=\"xMinYMin meet\"\n viewBox=\"".concat(viewBox.x, " ").concat(viewBox.y, " ").concat(viewBox.width, " ").concat(viewBox.height, "\"\n width=\"100%\" height=\"100%\"\n>\n <g stroke=\"#000000\" stroke-width=\"0.1%\" fill=\"none\" transform=\"matrix(1,0,0,-1,0,0)\">\n ").concat(_prettyData.pd.xml(elements.join('\n')), "\n </g>\n</svg>");
};
exports["default"] = _default;

View File

@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _round = require("round10");
/**
* Copied and ported to code standard as the b-spline library is not maintained any longer.
* Source:
* https://github.com/thibauts/b-spline
* Copyright (c) 2015 Thibaut Séguy <thibaut.seguy@gmail.com>
*/
var _default = function _default(t, degree, points, knots, weights) {
var n = points.length; // points count
var d = points[0].length; // point dimensionality
if (t < 0 || t > 1) {
throw new Error('t out of bounds [0,1]: ' + t);
}
if (degree < 1) throw new Error('degree must be at least 1 (linear)');
if (degree > n - 1) throw new Error('degree must be less than or equal to point count - 1');
if (!weights) {
// build weight vector of length [n]
weights = [];
for (var i = 0; i < n; i++) {
weights[i] = 1;
}
}
if (!knots) {
// build knot vector of length [n + degree + 1]
knots = [];
for (var _i = 0; _i < n + degree + 1; _i++) {
knots[_i] = _i;
}
} else {
if (knots.length !== n + degree + 1) throw new Error('bad knot vector length');
}
var domain = [degree, knots.length - 1 - degree]; // remap t to the domain where the spline is defined
var low = knots[domain[0]];
var high = knots[domain[1]];
t = t * (high - low) + low; // Clamp to the upper & lower bounds instead of
// throwing an error like in the original lib
// https://github.com/bjnortier/dxf/issues/28
t = Math.max(t, low);
t = Math.min(t, high); // find s (the spline segment) for the [t] value provided
var s;
for (s = domain[0]; s < domain[1]; s++) {
if (t >= knots[s] && t <= knots[s + 1]) {
break;
}
} // convert points to homogeneous coordinates
var v = [];
for (var _i2 = 0; _i2 < n; _i2++) {
v[_i2] = [];
for (var j = 0; j < d; j++) {
v[_i2][j] = points[_i2][j] * weights[_i2];
}
v[_i2][d] = weights[_i2];
} // l (level) goes from 1 to the curve degree + 1
var alpha;
for (var l = 1; l <= degree + 1; l++) {
// build level l of the pyramid
for (var _i3 = s; _i3 > s - degree - 1 + l; _i3--) {
alpha = (t - knots[_i3]) / (knots[_i3 + degree + 1 - l] - knots[_i3]); // interpolate each component
for (var _j = 0; _j < d + 1; _j++) {
v[_i3][_j] = (1 - alpha) * v[_i3 - 1][_j] + alpha * v[_i3][_j];
}
}
} // convert back to cartesian and return
var result = [];
for (var _i4 = 0; _i4 < d; _i4++) {
result[_i4] = (0, _round.round10)(v[s][_i4] / v[s][d], -9);
}
return result;
};
exports["default"] = _default;

View File

@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = [[0, 0, 0], [255, 0, 0], [255, 255, 0], [0, 255, 0], [0, 255, 255], [0, 0, 255], [255, 0, 255], [255, 255, 255], [65, 65, 65], [128, 128, 128], [255, 0, 0], [255, 170, 170], [189, 0, 0], [189, 126, 126], [129, 0, 0], [129, 86, 86], [104, 0, 0], [104, 69, 69], [79, 0, 0], [79, 53, 53], [255, 63, 0], [255, 191, 170], [189, 46, 0], [189, 141, 126], [129, 31, 0], [129, 96, 86], [104, 25, 0], [104, 78, 69], [79, 19, 0], [79, 59, 53], [255, 127, 0], [255, 212, 170], [189, 94, 0], [189, 157, 126], [129, 64, 0], [129, 107, 86], [104, 52, 0], [104, 86, 69], [79, 39, 0], [79, 66, 53], [255, 191, 0], [255, 234, 170], [189, 141, 0], [189, 173, 126], [129, 96, 0], [129, 118, 86], [104, 78, 0], [104, 95, 69], [79, 59, 0], [79, 73, 53], [255, 255, 0], [255, 255, 170], [189, 189, 0], [189, 189, 126], [129, 129, 0], [129, 129, 86], [104, 104, 0], [104, 104, 69], [79, 79, 0], [79, 79, 53], [191, 255, 0], [234, 255, 170], [141, 189, 0], [173, 189, 126], [96, 129, 0], [118, 129, 86], [78, 104, 0], [95, 104, 69], [59, 79, 0], [73, 79, 53], [127, 255, 0], [212, 255, 170], [94, 189, 0], [157, 189, 126], [64, 129, 0], [107, 129, 86], [52, 104, 0], [86, 104, 69], [39, 79, 0], [66, 79, 53], [63, 255, 0], [191, 255, 170], [46, 189, 0], [141, 189, 126], [31, 129, 0], [96, 129, 86], [25, 104, 0], [78, 104, 69], [19, 79, 0], [59, 79, 53], [0, 255, 0], [170, 255, 170], [0, 189, 0], [126, 189, 126], [0, 129, 0], [86, 129, 86], [0, 104, 0], [69, 104, 69], [0, 79, 0], [53, 79, 53], [0, 255, 63], [170, 255, 191], [0, 189, 46], [126, 189, 141], [0, 129, 31], [86, 129, 96], [0, 104, 25], [69, 104, 78], [0, 79, 19], [53, 79, 59], [0, 255, 127], [170, 255, 212], [0, 189, 94], [126, 189, 157], [0, 129, 64], [86, 129, 107], [0, 104, 52], [69, 104, 86], [0, 79, 39], [53, 79, 66], [0, 255, 191], [170, 255, 234], [0, 189, 141], [126, 189, 173], [0, 129, 96], [86, 129, 118], [0, 104, 78], [69, 104, 95], [0, 79, 59], [53, 79, 73], [0, 255, 255], [170, 255, 255], [0, 189, 189], [126, 189, 189], [0, 129, 129], [86, 129, 129], [0, 104, 104], [69, 104, 104], [0, 79, 79], [53, 79, 79], [0, 191, 255], [170, 234, 255], [0, 141, 189], [126, 173, 189], [0, 96, 129], [86, 118, 129], [0, 78, 104], [69, 95, 104], [0, 59, 79], [53, 73, 79], [0, 127, 255], [170, 212, 255], [0, 94, 189], [126, 157, 189], [0, 64, 129], [86, 107, 129], [0, 52, 104], [69, 86, 104], [0, 39, 79], [53, 66, 79], [0, 63, 255], [170, 191, 255], [0, 46, 189], [126, 141, 189], [0, 31, 129], [86, 96, 129], [0, 25, 104], [69, 78, 104], [0, 19, 79], [53, 59, 79], [0, 0, 255], [170, 170, 255], [0, 0, 189], [126, 126, 189], [0, 0, 129], [86, 86, 129], [0, 0, 104], [69, 69, 104], [0, 0, 79], [53, 53, 79], [63, 0, 255], [191, 170, 255], [46, 0, 189], [141, 126, 189], [31, 0, 129], [96, 86, 129], [25, 0, 104], [78, 69, 104], [19, 0, 79], [59, 53, 79], [127, 0, 255], [212, 170, 255], [94, 0, 189], [157, 126, 189], [64, 0, 129], [107, 86, 129], [52, 0, 104], [86, 69, 104], [39, 0, 79], [66, 53, 79], [191, 0, 255], [234, 170, 255], [141, 0, 189], [173, 126, 189], [96, 0, 129], [118, 86, 129], [78, 0, 104], [95, 69, 104], [59, 0, 79], [73, 53, 79], [255, 0, 255], [255, 170, 255], [189, 0, 189], [189, 126, 189], [129, 0, 129], [129, 86, 129], [104, 0, 104], [104, 69, 104], [79, 0, 79], [79, 53, 79], [255, 0, 191], [255, 170, 234], [189, 0, 141], [189, 126, 173], [129, 0, 96], [129, 86, 118], [104, 0, 78], [104, 69, 95], [79, 0, 59], [79, 53, 73], [255, 0, 127], [255, 170, 212], [189, 0, 94], [189, 126, 157], [129, 0, 64], [129, 86, 107], [104, 0, 52], [104, 69, 86], [79, 0, 39], [79, 53, 66], [255, 0, 63], [255, 170, 191], [189, 0, 46], [189, 126, 141], [129, 0, 31], [129, 86, 96], [104, 0, 25], [104, 69, 78], [79, 0, 19], [79, 53, 59], [51, 51, 51], [80, 80, 80], [105, 105, 105], [130, 130, 130], [190, 190, 190], [255, 255, 255]];
exports["default"] = _default;

View File

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _vecks = require("vecks");
/**
* Create the arcs point for a LWPOLYLINE. The start and end are excluded
*
* See diagram.png in this directory for description of points and angles used.
*/
var _default = function _default(from, to, bulge, resolution) {
// Resolution in degrees
if (!resolution) {
resolution = 5;
} // If the bulge is < 0, the arc goes clockwise. So we simply
// reverse a and b and invert sign
// Bulge = tan(theta/4)
var theta;
var a;
var b;
if (bulge < 0) {
theta = Math.atan(-bulge) * 4;
a = new _vecks.V2(from[0], from[1]);
b = new _vecks.V2(to[0], to[1]);
} else {
// Default is counter-clockwise
theta = Math.atan(bulge) * 4;
a = new _vecks.V2(to[0], to[1]);
b = new _vecks.V2(from[0], from[1]);
}
var ab = b.sub(a);
var lengthAB = ab.length();
var c = a.add(ab.multiply(0.5)); // Distance from center of arc to line between form and to points
var lengthCD = Math.abs(lengthAB / 2 / Math.tan(theta / 2));
var normAB = ab.norm();
var d;
if (theta < Math.PI) {
var normDC = new _vecks.V2(normAB.x * Math.cos(Math.PI / 2) - normAB.y * Math.sin(Math.PI / 2), normAB.y * Math.cos(Math.PI / 2) + normAB.x * Math.sin(Math.PI / 2)); // D is the center of the arc
d = c.add(normDC.multiply(-lengthCD));
} else {
var normCD = new _vecks.V2(normAB.x * Math.cos(Math.PI / 2) - normAB.y * Math.sin(Math.PI / 2), normAB.y * Math.cos(Math.PI / 2) + normAB.x * Math.sin(Math.PI / 2)); // D is the center of the arc
d = c.add(normCD.multiply(lengthCD));
} // Add points between start start and eng angle relative
// to the center point
var startAngle = Math.atan2(b.y - d.y, b.x - d.x) / Math.PI * 180;
var endAngle = Math.atan2(a.y - d.y, a.x - d.x) / Math.PI * 180;
if (endAngle < startAngle) {
endAngle += 360;
}
var r = b.sub(d).length();
var startInter = Math.floor(startAngle / resolution) * resolution + resolution;
var endInter = Math.ceil(endAngle / resolution) * resolution - resolution;
var points = [];
for (var i = startInter; i <= endInter; i += resolution) {
points.push(d.add(new _vecks.V2(Math.cos(i / 180 * Math.PI) * r, Math.sin(i / 180 * Math.PI) * r)));
} // Maintain the right ordering to join the from and to points
if (bulge < 0) {
points.reverse();
}
return points.map(function (p) {
return [p.x, p.y];
});
};
exports["default"] = _default;

View File

@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**
* Knot insertion is known as "Boehm's algorithm"
*
* https://math.stackexchange.com/questions/417859/convert-a-b-spline-into-bezier-curves
* code adapted from http://preserve.mactech.com/articles/develop/issue_25/schneider.html
*/
var _default = function _default(k, controlPoints, knots, newKnot) {
var x = knots;
var b = controlPoints;
var n = controlPoints.length;
var i = 0;
var foundIndex = false;
for (var j = 0; j < n + k; j++) {
if (newKnot > x[j] && newKnot <= x[j + 1]) {
i = j;
foundIndex = true;
break;
}
}
if (!foundIndex) {
throw new Error('invalid new knot');
}
var xHat = [];
for (var _j = 0; _j < n + k + 1; _j++) {
if (_j <= i) {
xHat[_j] = x[_j];
} else if (_j === i + 1) {
xHat[_j] = newKnot;
} else {
xHat[_j] = x[_j - 1];
}
}
var alpha;
var bHat = [];
for (var _j2 = 0; _j2 < n + 1; _j2++) {
if (_j2 <= i - k + 1) {
alpha = 1;
} else if (i - k + 2 <= _j2 && _j2 <= i) {
if (x[_j2 + k - 1] - x[_j2] === 0) {
alpha = 0;
} else {
alpha = (newKnot - x[_j2]) / (x[_j2 + k - 1] - x[_j2]);
}
} else {
alpha = 0;
}
if (alpha === 0) {
bHat[_j2] = b[_j2 - 1];
} else if (alpha === 1) {
bHat[_j2] = b[_j2];
} else {
bHat[_j2] = {
x: (1 - alpha) * b[_j2 - 1].x + alpha * b[_j2].x,
y: (1 - alpha) * b[_j2 - 1].y + alpha * b[_j2].y
};
}
}
return {
controlPoints: bHat,
knots: xHat
};
};
exports["default"] = _default;

View File

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../config"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function info() {
if (_config["default"].verbose) {
console.info.apply(undefined, arguments);
}
}
function warn() {
if (_config["default"].verbose) {
console.warn.apply(undefined, arguments);
}
}
function error() {
console.error.apply(undefined, arguments);
}
var _default = {
info: info,
warn: warn,
error: error
};
exports["default"] = _default;

View File

@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**
* Convert an RGB array to a CSS string definition.
* Converts white lines to black as the default.
*/
var _default = function _default(rgb) {
if (rgb[0] === 255 && rgb[1] === 255 && rgb[2] === 255) {
return 'rgb(0, 0, 0)';
} else {
return "rgb(".concat(rgb[0], ", ").concat(rgb[1], ", ").concat(rgb[2], ")");
}
};
exports["default"] = _default;

View File

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**
* Rotate a points by the given angle.
*
* @param points the points
* @param angle the rotation angle
*/
var _default = function _default(p, angle) {
return {
x: p.x * Math.cos(angle) - p.y * Math.sin(angle),
y: p.y * Math.cos(angle) + p.x * Math.sin(angle)
};
};
exports["default"] = _default;

View File

@ -0,0 +1,90 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.computeInsertions = exports.multiplicity = exports.checkPinned = void 0;
var _insertKnot = _interopRequireDefault(require("./insertKnot"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* For a pinned spline, the knots have to be repeated k times
* (where k is the order), at both the beginning and the end
*/
var checkPinned = function checkPinned(k, knots) {
// Pinned at the start
for (var i = 1; i < k; ++i) {
if (knots[i] !== knots[0]) {
throw Error("not pinned. order: ".concat(k, " knots: ").concat(knots));
}
} // Pinned at the end
for (var _i = knots.length - 2; _i > knots.length - k - 1; --_i) {
if (knots[_i] !== knots[knots.length - 1]) {
throw Error("not pinned. order: ".concat(k, " knots: ").concat(knots));
}
}
};
exports.checkPinned = checkPinned;
var multiplicity = function multiplicity(knots, index) {
var m = 1;
for (var i = index + 1; i < knots.length; ++i) {
if (knots[i] === knots[index]) {
++m;
} else {
break;
}
}
return m;
};
/**
* https://saccade.com/writing/graphics/KnotVectors.pdf
* A quadratic piecewise Bézier knot vector with seven control points
* will look like this [0 0 0 1 1 2 2 3 3 3]. In general, in a
* piecewise Bézier knot vector the first k knots are the same,
* then each subsequent group of k-1 knots is the same,
* until you get to the end.
*/
exports.multiplicity = multiplicity;
var computeInsertions = function computeInsertions(k, knots) {
var inserts = [];
var i = k;
while (i < knots.length - k) {
var knot = knots[i];
var m = multiplicity(knots, i);
for (var j = 0; j < k - m - 1; ++j) {
inserts.push(knot);
}
i = i + m;
}
return inserts;
};
exports.computeInsertions = computeInsertions;
var _default = function _default(k, controlPoints, knots) {
checkPinned(k, knots);
var insertions = computeInsertions(k, knots);
return insertions.reduce(function (acc, tNew) {
return (0, _insertKnot["default"])(k, acc.controlPoints, acc.knots, tNew);
}, {
controlPoints: controlPoints,
knots: knots
});
};
exports["default"] = _default;

View File

@ -0,0 +1,118 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _vecks = require("vecks");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
/**
* Transform the bounding box and the SVG element by the given
* transforms. The <g> element are created in reverse transform
* order and the bounding box in the given order.
*/
var _default = function _default(bbox, element, transforms) {
var transformedElement = '';
var matrices = transforms.map(function (transform) {
// Create the transformation matrix
var tx = transform.x || 0;
var ty = transform.y || 0;
var sx = transform.scaleX || 1;
var sy = transform.scaleY || 1;
var angle = (transform.rotation || 0) / 180 * Math.PI;
var cos = Math.cos,
sin = Math.sin;
var a, b, c, d, e, f; // In DXF an extrusionZ value of -1 denote a tranform around the Y axis.
if (transform.extrusionZ === -1) {
a = -sx * cos(angle);
b = sx * sin(angle);
c = sy * sin(angle);
d = sy * cos(angle);
e = -tx;
f = ty;
} else {
a = sx * cos(angle);
b = sx * sin(angle);
c = -sy * sin(angle);
d = sy * cos(angle);
e = tx;
f = ty;
}
return [a, b, c, d, e, f];
}); // Only transform the bounding box is it is valid (i.e. not Infinity)
var transformedBBox = new _vecks.Box2();
if (bbox.valid) {
var bboxPoints = [{
x: bbox.min.x,
y: bbox.min.y
}, {
x: bbox.max.x,
y: bbox.min.y
}, {
x: bbox.max.x,
y: bbox.max.y
}, {
x: bbox.min.x,
y: bbox.max.y
}];
matrices.forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 6),
a = _ref2[0],
b = _ref2[1],
c = _ref2[2],
d = _ref2[3],
e = _ref2[4],
f = _ref2[5];
bboxPoints = bboxPoints.map(function (point) {
return {
x: point.x * a + point.y * c + e,
y: point.x * b + point.y * d + f
};
});
});
transformedBBox = bboxPoints.reduce(function (acc, point) {
return acc.expandByPoint(point);
}, new _vecks.Box2());
}
matrices.reverse();
matrices.forEach(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 6),
a = _ref4[0],
b = _ref4[1],
c = _ref4[2],
d = _ref4[3],
e = _ref4[4],
f = _ref4[5];
transformedElement += "<g transform=\"matrix(".concat(a, " ").concat(b, " ").concat(c, " ").concat(d, " ").concat(e, " ").concat(f, ")\">");
});
transformedElement += element;
matrices.forEach(function (transform) {
transformedElement += '</g>';
});
return {
bbox: transformedBBox,
element: transformedElement
};
};
exports["default"] = _default;

View File

@ -0,0 +1,419 @@
2.20.3 / 2019-10-11
==================
* Support Node.js 0.10 (Revert #1059)
* Ran "npm unpublish commander@2.20.2". There is no 2.20.2.
2.20.1 / 2019-09-29
==================
* Improve executable subcommand tracking
* Update dev dependencies
2.20.0 / 2019-04-02
==================
* fix: resolve symbolic links completely when hunting for subcommands (#935)
* Update index.d.ts (#930)
* Update Readme.md (#924)
* Remove --save option as it isn't required anymore (#918)
* Add link to the license file (#900)
* Added example of receiving args from options (#858)
* Added missing semicolon (#882)
* Add extension to .eslintrc (#876)
2.19.0 / 2018-10-02
==================
* Removed newline after Options and Commands headers (#864)
* Bugfix - Error output (#862)
* Fix to change default value to string (#856)
2.18.0 / 2018-09-07
==================
* Standardize help output (#853)
* chmod 644 travis.yml (#851)
* add support for execute typescript subcommand via ts-node (#849)
2.17.1 / 2018-08-07
==================
* Fix bug in command emit (#844)
2.17.0 / 2018-08-03
==================
* fixed newline output after help information (#833)
* Fix to emit the action even without command (#778)
* npm update (#823)
2.16.0 / 2018-06-29
==================
* Remove Makefile and `test/run` (#821)
* Make 'npm test' run on Windows (#820)
* Add badge to display install size (#807)
* chore: cache node_modules (#814)
* chore: remove Node.js 4 (EOL), add Node.js 10 (#813)
* fixed typo in readme (#812)
* Fix types (#804)
* Update eslint to resolve vulnerabilities in lodash (#799)
* updated readme with custom event listeners. (#791)
* fix tests (#794)
2.15.0 / 2018-03-07
==================
* Update downloads badge to point to graph of downloads over time instead of duplicating link to npm
* Arguments description
2.14.1 / 2018-02-07
==================
* Fix typing of help function
2.14.0 / 2018-02-05
==================
* only register the option:version event once
* Fixes issue #727: Passing empty string for option on command is set to undefined
* enable eqeqeq rule
* resolves #754 add linter configuration to project
* resolves #560 respect custom name for version option
* document how to override the version flag
* document using options per command
2.13.0 / 2018-01-09
==================
* Do not print default for --no-
* remove trailing spaces in command help
* Update CI's Node.js to LTS and latest version
* typedefs: Command and Option types added to commander namespace
2.12.2 / 2017-11-28
==================
* fix: typings are not shipped
2.12.1 / 2017-11-23
==================
* Move @types/node to dev dependency
2.12.0 / 2017-11-22
==================
* add attributeName() method to Option objects
* Documentation updated for options with --no prefix
* typings: `outputHelp` takes a string as the first parameter
* typings: use overloads
* feat(typings): update to match js api
* Print default value in option help
* Fix translation error
* Fail when using same command and alias (#491)
* feat(typings): add help callback
* fix bug when description is add after command with options (#662)
* Format js code
* Rename History.md to CHANGELOG.md (#668)
* feat(typings): add typings to support TypeScript (#646)
* use current node
2.11.0 / 2017-07-03
==================
* Fix help section order and padding (#652)
* feature: support for signals to subcommands (#632)
* Fixed #37, --help should not display first (#447)
* Fix translation errors. (#570)
* Add package-lock.json
* Remove engines
* Upgrade package version
* Prefix events to prevent conflicts between commands and options (#494)
* Removing dependency on graceful-readlink
* Support setting name in #name function and make it chainable
* Add .vscode directory to .gitignore (Visual Studio Code metadata)
* Updated link to ruby commander in readme files
2.10.0 / 2017-06-19
==================
* Update .travis.yml. drop support for older node.js versions.
* Fix require arguments in README.md
* On SemVer you do not start from 0.0.1
* Add missing semi colon in readme
* Add save param to npm install
* node v6 travis test
* Update Readme_zh-CN.md
* Allow literal '--' to be passed-through as an argument
* Test subcommand alias help
* link build badge to master branch
* Support the alias of Git style sub-command
* added keyword commander for better search result on npm
* Fix Sub-Subcommands
* test node.js stable
* Fixes TypeError when a command has an option called `--description`
* Update README.md to make it beginner friendly and elaborate on the difference between angled and square brackets.
* Add chinese Readme file
2.9.0 / 2015-10-13
==================
* Add option `isDefault` to set default subcommand #415 @Qix-
* Add callback to allow filtering or post-processing of help text #434 @djulien
* Fix `undefined` text in help information close #414 #416 @zhiyelee
2.8.1 / 2015-04-22
==================
* Back out `support multiline description` Close #396 #397
2.8.0 / 2015-04-07
==================
* Add `process.execArg` support, execution args like `--harmony` will be passed to sub-commands #387 @DigitalIO @zhiyelee
* Fix bug in Git-style sub-commands #372 @zhiyelee
* Allow commands to be hidden from help #383 @tonylukasavage
* When git-style sub-commands are in use, yet none are called, display help #382 @claylo
* Add ability to specify arguments syntax for top-level command #258 @rrthomas
* Support multiline descriptions #208 @zxqfox
2.7.1 / 2015-03-11
==================
* Revert #347 (fix collisions when option and first arg have same name) which causes a bug in #367.
2.7.0 / 2015-03-09
==================
* Fix git-style bug when installed globally. Close #335 #349 @zhiyelee
* Fix collisions when option and first arg have same name. Close #346 #347 @tonylukasavage
* Add support for camelCase on `opts()`. Close #353 @nkzawa
* Add node.js 0.12 and io.js to travis.yml
* Allow RegEx options. #337 @palanik
* Fixes exit code when sub-command failing. Close #260 #332 @pirelenito
* git-style `bin` files in $PATH make sense. Close #196 #327 @zhiyelee
2.6.0 / 2014-12-30
==================
* added `Command#allowUnknownOption` method. Close #138 #318 @doozr @zhiyelee
* Add application description to the help msg. Close #112 @dalssoft
2.5.1 / 2014-12-15
==================
* fixed two bugs incurred by variadic arguments. Close #291 @Quentin01 #302 @zhiyelee
2.5.0 / 2014-10-24
==================
* add support for variadic arguments. Closes #277 @whitlockjc
2.4.0 / 2014-10-17
==================
* fixed a bug on executing the coercion function of subcommands option. Closes #270
* added `Command.prototype.name` to retrieve command name. Closes #264 #266 @tonylukasavage
* added `Command.prototype.opts` to retrieve all the options as a simple object of key-value pairs. Closes #262 @tonylukasavage
* fixed a bug on subcommand name. Closes #248 @jonathandelgado
* fixed function normalize doesnt honor option terminator. Closes #216 @abbr
2.3.0 / 2014-07-16
==================
* add command alias'. Closes PR #210
* fix: Typos. Closes #99
* fix: Unused fs module. Closes #217
2.2.0 / 2014-03-29
==================
* add passing of previous option value
* fix: support subcommands on windows. Closes #142
* Now the defaultValue passed as the second argument of the coercion function.
2.1.0 / 2013-11-21
==================
* add: allow cflag style option params, unit test, fixes #174
2.0.0 / 2013-07-18
==================
* remove input methods (.prompt, .confirm, etc)
1.3.2 / 2013-07-18
==================
* add support for sub-commands to co-exist with the original command
1.3.1 / 2013-07-18
==================
* add quick .runningCommand hack so you can opt-out of other logic when running a sub command
1.3.0 / 2013-07-09
==================
* add EACCES error handling
* fix sub-command --help
1.2.0 / 2013-06-13
==================
* allow "-" hyphen as an option argument
* support for RegExp coercion
1.1.1 / 2012-11-20
==================
* add more sub-command padding
* fix .usage() when args are present. Closes #106
1.1.0 / 2012-11-16
==================
* add git-style executable subcommand support. Closes #94
1.0.5 / 2012-10-09
==================
* fix `--name` clobbering. Closes #92
* fix examples/help. Closes #89
1.0.4 / 2012-09-03
==================
* add `outputHelp()` method.
1.0.3 / 2012-08-30
==================
* remove invalid .version() defaulting
1.0.2 / 2012-08-24
==================
* add `--foo=bar` support [arv]
* fix password on node 0.8.8. Make backward compatible with 0.6 [focusaurus]
1.0.1 / 2012-08-03
==================
* fix issue #56
* fix tty.setRawMode(mode) was moved to tty.ReadStream#setRawMode() (i.e. process.stdin.setRawMode())
1.0.0 / 2012-07-05
==================
* add support for optional option descriptions
* add defaulting of `.version()` to package.json's version
0.6.1 / 2012-06-01
==================
* Added: append (yes or no) on confirmation
* Added: allow node.js v0.7.x
0.6.0 / 2012-04-10
==================
* Added `.prompt(obj, callback)` support. Closes #49
* Added default support to .choose(). Closes #41
* Fixed the choice example
0.5.1 / 2011-12-20
==================
* Fixed `password()` for recent nodes. Closes #36
0.5.0 / 2011-12-04
==================
* Added sub-command option support [itay]
0.4.3 / 2011-12-04
==================
* Fixed custom help ordering. Closes #32
0.4.2 / 2011-11-24
==================
* Added travis support
* Fixed: line-buffered input automatically trimmed. Closes #31
0.4.1 / 2011-11-18
==================
* Removed listening for "close" on --help
0.4.0 / 2011-11-15
==================
* Added support for `--`. Closes #24
0.3.3 / 2011-11-14
==================
* Fixed: wait for close event when writing help info [Jerry Hamlet]
0.3.2 / 2011-11-01
==================
* Fixed long flag definitions with values [felixge]
0.3.1 / 2011-10-31
==================
* Changed `--version` short flag to `-V` from `-v`
* Changed `.version()` so it's configurable [felixge]
0.3.0 / 2011-10-31
==================
* Added support for long flags only. Closes #18
0.2.1 / 2011-10-24
==================
* "node": ">= 0.4.x < 0.7.0". Closes #20
0.2.0 / 2011-09-26
==================
* Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
0.1.0 / 2011-08-24
==================
* Added support for custom `--help` output
0.0.5 / 2011-08-18
==================
* Changed: when the user enters nothing prompt for password again
* Fixed issue with passwords beginning with numbers [NuckChorris]
0.0.4 / 2011-08-15
==================
* Fixed `Commander#args`
0.0.3 / 2011-08-15
==================
* Added default option value support
0.0.2 / 2011-08-15
==================
* Added mask support to `Command#password(str[, mask], fn)`
* Added `Command#password(str, fn)`
0.0.1 / 2010-01-03
==================
* Initial release

View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,428 @@
# Commander.js
[![Build Status](https://api.travis-ci.org/tj/commander.js.svg?branch=master)](http://travis-ci.org/tj/commander.js)
[![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander)
[![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://npmcharts.com/compare/commander?minimal=true)
[![Install Size](https://packagephobia.now.sh/badge?p=commander)](https://packagephobia.now.sh/result?p=commander)
[![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).
[API documentation](http://tj.github.com/commander.js/)
## Installation
$ npm install commander
## Option parsing
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.version('0.1.0')
.option('-p, --peppers', 'Add peppers')
.option('-P, --pineapple', 'Add pineapple')
.option('-b, --bbq-sauce', 'Add bbq sauce')
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
.parse(process.argv);
console.log('you ordered a pizza with:');
if (program.peppers) console.log(' - peppers');
if (program.pineapple) console.log(' - pineapple');
if (program.bbqSauce) console.log(' - bbq');
console.log(' - %s cheese', program.cheese);
```
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.option('--no-sauce', 'Remove sauce')
.parse(process.argv);
console.log('you ordered a pizza');
if (program.sauce) console.log(' with sauce');
else console.log(' without sauce');
```
To get string arguments from options you will need to use angle brackets <> for required inputs or square brackets [] for optional inputs.
e.g. ```.option('-m --myarg [myVar]', 'my super cool description')```
Then to access the input if it was passed in.
e.g. ```var myInput = program.myarg```
**NOTE**: If you pass a argument without using brackets the example above will return true and not the value passed in.
## Version option
Calling the `version` implicitly adds the `-V` and `--version` options to the command.
When either of these options is present, the command prints the version number and exits.
$ ./examples/pizza -V
0.0.1
If you want your program to respond to the `-v` option instead of the `-V` option, simply pass custom flags to the `version` method using the same syntax as the `option` method.
```js
program
.version('0.0.1', '-v, --version')
```
The version flags can be named anything, but the long option is required.
## Command-specific options
You can attach options to a command.
```js
#!/usr/bin/env node
var program = require('commander');
program
.command('rm <dir>')
.option('-r, --recursive', 'Remove recursively')
.action(function (dir, cmd) {
console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
})
program.parse(process.argv)
```
A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated.
## Coercion
```js
function range(val) {
return val.split('..').map(Number);
}
function list(val) {
return val.split(',');
}
function collect(val, memo) {
memo.push(val);
return memo;
}
function increaseVerbosity(v, total) {
return total + 1;
}
program
.version('0.1.0')
.usage('[options] <file ...>')
.option('-i, --integer <n>', 'An integer argument', parseInt)
.option('-f, --float <n>', 'A float argument', parseFloat)
.option('-r, --range <a>..<b>', 'A range', range)
.option('-l, --list <items>', 'A list', list)
.option('-o, --optional [value]', 'An optional value')
.option('-c, --collect [value]', 'A repeatable value', collect, [])
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
.parse(process.argv);
console.log(' int: %j', program.integer);
console.log(' float: %j', program.float);
console.log(' optional: %j', program.optional);
program.range = program.range || [];
console.log(' range: %j..%j', program.range[0], program.range[1]);
console.log(' list: %j', program.list);
console.log(' collect: %j', program.collect);
console.log(' verbosity: %j', program.verbose);
console.log(' args: %j', program.args);
```
## Regular Expression
```js
program
.version('0.1.0')
.option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
.option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
.parse(process.argv);
console.log(' size: %j', program.size);
console.log(' drink: %j', program.drink);
```
## Variadic arguments
The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to
append `...` to the argument name. Here is an example:
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.version('0.1.0')
.command('rmdir <dir> [otherDirs...]')
.action(function (dir, otherDirs) {
console.log('rmdir %s', dir);
if (otherDirs) {
otherDirs.forEach(function (oDir) {
console.log('rmdir %s', oDir);
});
}
});
program.parse(process.argv);
```
An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed
to your action as demonstrated above.
## Specify the argument syntax
```js
#!/usr/bin/env node
var program = require('commander');
program
.version('0.1.0')
.arguments('<cmd> [env]')
.action(function (cmd, env) {
cmdValue = cmd;
envValue = env;
});
program.parse(process.argv);
if (typeof cmdValue === 'undefined') {
console.error('no command given!');
process.exit(1);
}
console.log('command:', cmdValue);
console.log('environment:', envValue || "no environment given");
```
Angled brackets (e.g. `<cmd>`) indicate required input. Square brackets (e.g. `[env]`) indicate optional input.
## Git-style sub-commands
```js
// file: ./examples/pm
var program = require('commander');
program
.version('0.1.0')
.command('install [name]', 'install one or more packages')
.command('search [query]', 'search with optional query')
.command('list', 'list packages installed', {isDefault: true})
.parse(process.argv);
```
When `.command()` is invoked with a description argument, no `.action(callback)` should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like `git(1)` and other popular tools.
The commander will try to search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-command`, like `pm-install`, `pm-search`.
Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the subcommand from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
### `--harmony`
You can enable `--harmony` option in two ways:
* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version dont support this pattern.
* Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning sub-command process.
## Automated --help
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
```
$ ./examples/pizza --help
Usage: pizza [options]
An application for pizzas ordering
Options:
-h, --help output usage information
-V, --version output the version number
-p, --peppers Add peppers
-P, --pineapple Add pineapple
-b, --bbq Add bbq sauce
-c, --cheese <type> Add the specified type of cheese [marble]
-C, --no-cheese You do not want any cheese
```
## Custom help
You can display arbitrary `-h, --help` information
by listening for "--help". Commander will automatically
exit once you are done so that the remainder of your program
does not execute causing undesired behaviors, for example
in the following executable "stuff" will not output when
`--help` is used.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.version('0.1.0')
.option('-f, --foo', 'enable some foo')
.option('-b, --bar', 'enable some bar')
.option('-B, --baz', 'enable some baz');
// must be before .parse() since
// node's emit() is immediate
program.on('--help', function(){
console.log('')
console.log('Examples:');
console.log(' $ custom-help --help');
console.log(' $ custom-help -h');
});
program.parse(process.argv);
console.log('stuff');
```
Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
```
Usage: custom-help [options]
Options:
-h, --help output usage information
-V, --version output the version number
-f, --foo enable some foo
-b, --bar enable some bar
-B, --baz enable some baz
Examples:
$ custom-help --help
$ custom-help -h
```
## .outputHelp(cb)
Output help information without exiting.
Optional callback cb allows post-processing of help text before it is displayed.
If you want to display help by default (e.g. if no command was provided), you can use something like:
```js
var program = require('commander');
var colors = require('colors');
program
.version('0.1.0')
.command('getstream [url]', 'get stream URL')
.parse(process.argv);
if (!process.argv.slice(2).length) {
program.outputHelp(make_red);
}
function make_red(txt) {
return colors.red(txt); //display the help text in red on the console
}
```
## .help(cb)
Output help information and exit immediately.
Optional callback cb allows post-processing of help text before it is displayed.
## Custom event listeners
You can execute custom actions by listening to command and option events.
```js
program.on('option:verbose', function () {
process.env.VERBOSE = this.verbose;
});
// error on unknown commands
program.on('command:*', function () {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
});
```
## Examples
```js
var program = require('commander');
program
.version('0.1.0')
.option('-C, --chdir <path>', 'change the working directory')
.option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
.option('-T, --no-tests', 'ignore test hook');
program
.command('setup [env]')
.description('run setup commands for all envs')
.option("-s, --setup_mode [mode]", "Which setup mode to use")
.action(function(env, options){
var mode = options.setup_mode || "normal";
env = env || 'all';
console.log('setup for %s env(s) with %s mode', env, mode);
});
program
.command('exec <cmd>')
.alias('ex')
.description('execute the given remote cmd')
.option("-e, --exec_mode <mode>", "Which exec mode to use")
.action(function(cmd, options){
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
}).on('--help', function() {
console.log('');
console.log('Examples:');
console.log('');
console.log(' $ deploy exec sequential');
console.log(' $ deploy exec async');
});
program
.command('*')
.action(function(env){
console.log('deploying "%s"', env);
});
program.parse(process.argv);
```
More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
## License
[MIT](https://github.com/tj/commander.js/blob/master/LICENSE)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
{
"_from": "commander@^2.20.3",
"_id": "commander@2.20.3",
"_inBundle": false,
"_integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"_location": "/dxf/commander",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "commander@^2.20.3",
"name": "commander",
"escapedName": "commander",
"rawSpec": "^2.20.3",
"saveSpec": null,
"fetchSpec": "^2.20.3"
},
"_requiredBy": [
"/dxf"
],
"_resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"_shasum": "fd485e84c03eb4881c20722ba48035e8531aeb33",
"_spec": "commander@^2.20.3",
"_where": "C:\\node-v10.18.0-win-x64\\node_modules\\dxf",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"bugs": {
"url": "https://github.com/tj/commander.js/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "the complete solution for node.js command-line programs",
"devDependencies": {
"@types/node": "^12.7.8",
"eslint": "^6.4.0",
"should": "^13.2.3",
"sinon": "^7.5.0",
"standard": "^14.3.1",
"ts-node": "^8.4.1",
"typescript": "^3.6.3"
},
"files": [
"index.js",
"typings/index.d.ts"
],
"homepage": "https://github.com/tj/commander.js#readme",
"keywords": [
"commander",
"command",
"option",
"parser"
],
"license": "MIT",
"main": "index",
"name": "commander",
"repository": {
"type": "git",
"url": "git+https://github.com/tj/commander.js.git"
},
"scripts": {
"lint": "eslint index.js",
"test": "node test/run.js && npm run test-typings",
"test-typings": "tsc -p tsconfig.json"
},
"typings": "typings/index.d.ts",
"version": "2.20.3"
}

View File

@ -0,0 +1,310 @@
// Type definitions for commander 2.11
// Project: https://github.com/visionmedia/commander.js
// Definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>, Jules Randolph <https://github.com/sveinburne>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare namespace local {
class Option {
flags: string;
required: boolean;
optional: boolean;
bool: boolean;
short?: string;
long: string;
description: string;
/**
* Initialize a new `Option` with the given `flags` and `description`.
*
* @param {string} flags
* @param {string} [description]
*/
constructor(flags: string, description?: string);
}
class Command extends NodeJS.EventEmitter {
[key: string]: any;
args: string[];
/**
* Initialize a new `Command`.
*
* @param {string} [name]
*/
constructor(name?: string);
/**
* Set the program version to `str`.
*
* This method auto-registers the "-V, --version" flag
* which will print the version number when passed.
*
* @param {string} str
* @param {string} [flags]
* @returns {Command} for chaining
*/
version(str: string, flags?: string): Command;
/**
* Add command `name`.
*
* The `.action()` callback is invoked when the
* command `name` is specified via __ARGV__,
* and the remaining arguments are applied to the
* function for access.
*
* When the `name` is "*" an un-matched command
* will be passed as the first arg, followed by
* the rest of __ARGV__ remaining.
*
* @example
* program
* .version('0.0.1')
* .option('-C, --chdir <path>', 'change the working directory')
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
* .option('-T, --no-tests', 'ignore test hook')
*
* program
* .command('setup')
* .description('run remote setup commands')
* .action(function() {
* console.log('setup');
* });
*
* program
* .command('exec <cmd>')
* .description('run the given remote command')
* .action(function(cmd) {
* console.log('exec "%s"', cmd);
* });
*
* program
* .command('teardown <dir> [otherDirs...]')
* .description('run teardown commands')
* .action(function(dir, otherDirs) {
* console.log('dir "%s"', dir);
* if (otherDirs) {
* otherDirs.forEach(function (oDir) {
* console.log('dir "%s"', oDir);
* });
* }
* });
*
* program
* .command('*')
* .description('deploy the given env')
* .action(function(env) {
* console.log('deploying "%s"', env);
* });
*
* program.parse(process.argv);
*
* @param {string} name
* @param {string} [desc] for git-style sub-commands
* @param {CommandOptions} [opts] command options
* @returns {Command} the new command
*/
command(name: string, desc?: string, opts?: commander.CommandOptions): Command;
/**
* Define argument syntax for the top-level command.
*
* @param {string} desc
* @returns {Command} for chaining
*/
arguments(desc: string): Command;
/**
* Parse expected `args`.
*
* For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
*
* @param {string[]} args
* @returns {Command} for chaining
*/
parseExpectedArgs(args: string[]): Command;
/**
* Register callback `fn` for the command.
*
* @example
* program
* .command('help')
* .description('display verbose help')
* .action(function() {
* // output help here
* });
*
* @param {(...args: any[]) => void} fn
* @returns {Command} for chaining
*/
action(fn: (...args: any[]) => void): Command;
/**
* Define option with `flags`, `description` and optional
* coercion `fn`.
*
* The `flags` string should contain both the short and long flags,
* separated by comma, a pipe or space. The following are all valid
* all will output this way when `--help` is used.
*
* "-p, --pepper"
* "-p|--pepper"
* "-p --pepper"
*
* @example
* // simple boolean defaulting to false
* program.option('-p, --pepper', 'add pepper');
*
* --pepper
* program.pepper
* // => Boolean
*
* // simple boolean defaulting to true
* program.option('-C, --no-cheese', 'remove cheese');
*
* program.cheese
* // => true
*
* --no-cheese
* program.cheese
* // => false
*
* // required argument
* program.option('-C, --chdir <path>', 'change the working directory');
*
* --chdir /tmp
* program.chdir
* // => "/tmp"
*
* // optional argument
* program.option('-c, --cheese [type]', 'add cheese [marble]');
*
* @param {string} flags
* @param {string} [description]
* @param {((arg1: any, arg2: any) => void) | RegExp} [fn] function or default
* @param {*} [defaultValue]
* @returns {Command} for chaining
*/
option(flags: string, description?: string, fn?: ((arg1: any, arg2: any) => void) | RegExp, defaultValue?: any): Command;
option(flags: string, description?: string, defaultValue?: any): Command;
/**
* Allow unknown options on the command line.
*
* @param {boolean} [arg] if `true` or omitted, no error will be thrown for unknown options.
* @returns {Command} for chaining
*/
allowUnknownOption(arg?: boolean): Command;
/**
* Parse `argv`, settings options and invoking commands when defined.
*
* @param {string[]} argv
* @returns {Command} for chaining
*/
parse(argv: string[]): Command;
/**
* Parse options from `argv` returning `argv` void of these options.
*
* @param {string[]} argv
* @returns {ParseOptionsResult}
*/
parseOptions(argv: string[]): commander.ParseOptionsResult;
/**
* Return an object containing options as key-value pairs
*
* @returns {{[key: string]: any}}
*/
opts(): { [key: string]: any };
/**
* Set the description to `str`.
*
* @param {string} str
* @param {{[argName: string]: string}} argsDescription
* @return {(Command | string)}
*/
description(str: string, argsDescription?: {[argName: string]: string}): Command;
description(): string;
/**
* Set an alias for the command.
*
* @param {string} alias
* @return {(Command | string)}
*/
alias(alias: string): Command;
alias(): string;
/**
* Set or get the command usage.
*
* @param {string} str
* @return {(Command | string)}
*/
usage(str: string): Command;
usage(): string;
/**
* Set the name of the command.
*
* @param {string} str
* @return {Command}
*/
name(str: string): Command;
/**
* Get the name of the command.
*
* @return {string}
*/
name(): string;
/**
* Output help information for this command.
*
* @param {(str: string) => string} [cb]
*/
outputHelp(cb?: (str: string) => string): void;
/** Output help information and exit.
*
* @param {(str: string) => string} [cb]
*/
help(cb?: (str: string) => string): never;
}
}
declare namespace commander {
type Command = local.Command
type Option = local.Option
interface CommandOptions {
noHelp?: boolean;
isDefault?: boolean;
}
interface ParseOptionsResult {
args: string[];
unknown: string[];
}
interface CommanderStatic extends Command {
Command: typeof local.Command;
Option: typeof local.Option;
CommandOptions: CommandOptions;
ParseOptionsResult: ParseOptionsResult;
}
}
declare const commander: commander.CommanderStatic;
export = commander;

View File

@ -0,0 +1,47 @@
Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
Based on Underscore.js, copyright Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/lodash/lodash
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code displayed within the prose of the
documentation.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
Files located in the node_modules and vendor directories are externally
maintained libraries used by this software which have their own
licenses; we recommend you read them, as their terms may differ from the
terms above.

View File

@ -0,0 +1,39 @@
# lodash v4.17.20
The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules.
## Installation
Using npm:
```shell
$ npm i -g npm
$ npm i --save lodash
```
In Node.js:
```js
// Load the full build.
var _ = require('lodash');
// Load the core build.
var _ = require('lodash/core');
// Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
// Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');
// Cherry-pick methods for smaller browserify/rollup/webpack bundles.
var at = require('lodash/at');
var curryN = require('lodash/fp/curryN');
```
See the [package source](https://github.com/lodash/lodash/tree/4.17.20-npm) for more details.
**Note:**<br>
Install [n_](https://www.npmjs.com/package/n_) for Lodash use in the Node.js < 6 REPL.
## Support
Tested in Chrome 74-75, Firefox 66-67, IE 11, Edge 18, Safari 11-12, & Node.js 8-12.<br>
Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available.

View File

@ -0,0 +1,7 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var DataView = getNative(root, 'DataView');
module.exports = DataView;

View File

@ -0,0 +1,32 @@
var hashClear = require('./_hashClear'),
hashDelete = require('./_hashDelete'),
hashGet = require('./_hashGet'),
hashHas = require('./_hashHas'),
hashSet = require('./_hashSet');
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
module.exports = Hash;

View File

@ -0,0 +1,28 @@
var baseCreate = require('./_baseCreate'),
baseLodash = require('./_baseLodash');
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295;
/**
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
*
* @private
* @constructor
* @param {*} value The value to wrap.
*/
function LazyWrapper(value) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
this.__takeCount__ = MAX_ARRAY_LENGTH;
this.__views__ = [];
}
// Ensure `LazyWrapper` is an instance of `baseLodash`.
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;
module.exports = LazyWrapper;

View File

@ -0,0 +1,32 @@
var listCacheClear = require('./_listCacheClear'),
listCacheDelete = require('./_listCacheDelete'),
listCacheGet = require('./_listCacheGet'),
listCacheHas = require('./_listCacheHas'),
listCacheSet = require('./_listCacheSet');
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
module.exports = ListCache;

View File

@ -0,0 +1,22 @@
var baseCreate = require('./_baseCreate'),
baseLodash = require('./_baseLodash');
/**
* The base constructor for creating `lodash` wrapper objects.
*
* @private
* @param {*} value The value to wrap.
* @param {boolean} [chainAll] Enable explicit method chain sequences.
*/
function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__chain__ = !!chainAll;
this.__index__ = 0;
this.__values__ = undefined;
}
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
LodashWrapper.prototype.constructor = LodashWrapper;
module.exports = LodashWrapper;

View File

@ -0,0 +1,7 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
module.exports = Map;

View File

@ -0,0 +1,32 @@
var mapCacheClear = require('./_mapCacheClear'),
mapCacheDelete = require('./_mapCacheDelete'),
mapCacheGet = require('./_mapCacheGet'),
mapCacheHas = require('./_mapCacheHas'),
mapCacheSet = require('./_mapCacheSet');
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
module.exports = MapCache;

View File

@ -0,0 +1,7 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Promise = getNative(root, 'Promise');
module.exports = Promise;

View File

@ -0,0 +1,7 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Set = getNative(root, 'Set');
module.exports = Set;

View File

@ -0,0 +1,27 @@
var MapCache = require('./_MapCache'),
setCacheAdd = require('./_setCacheAdd'),
setCacheHas = require('./_setCacheHas');
/**
*
* Creates an array cache object to store unique values.
*
* @private
* @constructor
* @param {Array} [values] The values to cache.
*/
function SetCache(values) {
var index = -1,
length = values == null ? 0 : values.length;
this.__data__ = new MapCache;
while (++index < length) {
this.add(values[index]);
}
}
// Add methods to `SetCache`.
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
SetCache.prototype.has = setCacheHas;
module.exports = SetCache;

View File

@ -0,0 +1,27 @@
var ListCache = require('./_ListCache'),
stackClear = require('./_stackClear'),
stackDelete = require('./_stackDelete'),
stackGet = require('./_stackGet'),
stackHas = require('./_stackHas'),
stackSet = require('./_stackSet');
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Stack(entries) {
var data = this.__data__ = new ListCache(entries);
this.size = data.size;
}
// Add methods to `Stack`.
Stack.prototype.clear = stackClear;
Stack.prototype['delete'] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;
module.exports = Stack;

View File

@ -0,0 +1,6 @@
var root = require('./_root');
/** Built-in value references. */
var Symbol = root.Symbol;
module.exports = Symbol;

View File

@ -0,0 +1,6 @@
var root = require('./_root');
/** Built-in value references. */
var Uint8Array = root.Uint8Array;
module.exports = Uint8Array;

View File

@ -0,0 +1,7 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var WeakMap = getNative(root, 'WeakMap');
module.exports = WeakMap;

View File

@ -0,0 +1,21 @@
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
switch (args.length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
module.exports = apply;

View File

@ -0,0 +1,22 @@
/**
* A specialized version of `baseAggregator` for arrays.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} setter The function to set `accumulator` values.
* @param {Function} iteratee The iteratee to transform keys.
* @param {Object} accumulator The initial aggregated object.
* @returns {Function} Returns `accumulator`.
*/
function arrayAggregator(array, setter, iteratee, accumulator) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
var value = array[index];
setter(accumulator, value, iteratee(value), array);
}
return accumulator;
}
module.exports = arrayAggregator;

View File

@ -0,0 +1,22 @@
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
module.exports = arrayEach;

View File

@ -0,0 +1,21 @@
/**
* A specialized version of `_.forEachRight` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEachRight(array, iteratee) {
var length = array == null ? 0 : array.length;
while (length--) {
if (iteratee(array[length], length, array) === false) {
break;
}
}
return array;
}
module.exports = arrayEachRight;

View File

@ -0,0 +1,23 @@
/**
* A specialized version of `_.every` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if all elements pass the predicate check,
* else `false`.
*/
function arrayEvery(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (!predicate(array[index], index, array)) {
return false;
}
}
return true;
}
module.exports = arrayEvery;

View File

@ -0,0 +1,25 @@
/**
* A specialized version of `_.filter` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
function arrayFilter(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length,
resIndex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result[resIndex++] = value;
}
}
return result;
}
module.exports = arrayFilter;

View File

@ -0,0 +1,17 @@
var baseIndexOf = require('./_baseIndexOf');
/**
* A specialized version of `_.includes` for arrays without support for
* specifying an index to search from.
*
* @private
* @param {Array} [array] The array to inspect.
* @param {*} target The value to search for.
* @returns {boolean} Returns `true` if `target` is found, else `false`.
*/
function arrayIncludes(array, value) {
var length = array == null ? 0 : array.length;
return !!length && baseIndexOf(array, value, 0) > -1;
}
module.exports = arrayIncludes;

View File

@ -0,0 +1,22 @@
/**
* This function is like `arrayIncludes` except that it accepts a comparator.
*
* @private
* @param {Array} [array] The array to inspect.
* @param {*} target The value to search for.
* @param {Function} comparator The comparator invoked per element.
* @returns {boolean} Returns `true` if `target` is found, else `false`.
*/
function arrayIncludesWith(array, value, comparator) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (comparator(value, array[index])) {
return true;
}
}
return false;
}
module.exports = arrayIncludesWith;

View File

@ -0,0 +1,49 @@
var baseTimes = require('./_baseTimes'),
isArguments = require('./isArguments'),
isArray = require('./isArray'),
isBuffer = require('./isBuffer'),
isIndex = require('./_isIndex'),
isTypedArray = require('./isTypedArray');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates an array of the enumerable property names of the array-like `value`.
*
* @private
* @param {*} value The value to query.
* @param {boolean} inherited Specify returning inherited property names.
* @returns {Array} Returns the array of property names.
*/
function arrayLikeKeys(value, inherited) {
var isArr = isArray(value),
isArg = !isArr && isArguments(value),
isBuff = !isArr && !isArg && isBuffer(value),
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
skipIndexes = isArr || isArg || isBuff || isType,
result = skipIndexes ? baseTimes(value.length, String) : [],
length = result.length;
for (var key in value) {
if ((inherited || hasOwnProperty.call(value, key)) &&
!(skipIndexes && (
// Safari 9 has enumerable `arguments.length` in strict mode.
key == 'length' ||
// Node.js 0.10 has enumerable non-index properties on buffers.
(isBuff && (key == 'offset' || key == 'parent')) ||
// PhantomJS 2 has enumerable non-index properties on typed arrays.
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
// Skip index properties.
isIndex(key, length)
))) {
result.push(key);
}
}
return result;
}
module.exports = arrayLikeKeys;

View File

@ -0,0 +1,21 @@
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
module.exports = arrayMap;

View File

@ -0,0 +1,20 @@
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
module.exports = arrayPush;

View File

@ -0,0 +1,26 @@
/**
* A specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the first element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array == null ? 0 : array.length;
if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iteratee(accumulator, array[index], index, array);
}
return accumulator;
}
module.exports = arrayReduce;

View File

@ -0,0 +1,24 @@
/**
* A specialized version of `_.reduceRight` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the last element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
var length = array == null ? 0 : array.length;
if (initAccum && length) {
accumulator = array[--length];
}
while (length--) {
accumulator = iteratee(accumulator, array[length], length, array);
}
return accumulator;
}
module.exports = arrayReduceRight;

View File

@ -0,0 +1,15 @@
var baseRandom = require('./_baseRandom');
/**
* A specialized version of `_.sample` for arrays.
*
* @private
* @param {Array} array The array to sample.
* @returns {*} Returns the random element.
*/
function arraySample(array) {
var length = array.length;
return length ? array[baseRandom(0, length - 1)] : undefined;
}
module.exports = arraySample;

View File

@ -0,0 +1,17 @@
var baseClamp = require('./_baseClamp'),
copyArray = require('./_copyArray'),
shuffleSelf = require('./_shuffleSelf');
/**
* A specialized version of `_.sampleSize` for arrays.
*
* @private
* @param {Array} array The array to sample.
* @param {number} n The number of elements to sample.
* @returns {Array} Returns the random elements.
*/
function arraySampleSize(array, n) {
return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
}
module.exports = arraySampleSize;

View File

@ -0,0 +1,15 @@
var copyArray = require('./_copyArray'),
shuffleSelf = require('./_shuffleSelf');
/**
* A specialized version of `_.shuffle` for arrays.
*
* @private
* @param {Array} array The array to shuffle.
* @returns {Array} Returns the new shuffled array.
*/
function arrayShuffle(array) {
return shuffleSelf(copyArray(array));
}
module.exports = arrayShuffle;

View File

@ -0,0 +1,23 @@
/**
* A specialized version of `_.some` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if any element passes the predicate check,
* else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
module.exports = arraySome;

View File

@ -0,0 +1,12 @@
var baseProperty = require('./_baseProperty');
/**
* Gets the size of an ASCII `string`.
*
* @private
* @param {string} string The string inspect.
* @returns {number} Returns the string size.
*/
var asciiSize = baseProperty('length');
module.exports = asciiSize;

View File

@ -0,0 +1,12 @@
/**
* Converts an ASCII `string` to an array.
*
* @private
* @param {string} string The string to convert.
* @returns {Array} Returns the converted array.
*/
function asciiToArray(string) {
return string.split('');
}
module.exports = asciiToArray;

View File

@ -0,0 +1,15 @@
/** Used to match words composed of alphanumeric characters. */
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
/**
* Splits an ASCII `string` into an array of its words.
*
* @private
* @param {string} The string to inspect.
* @returns {Array} Returns the words of `string`.
*/
function asciiWords(string) {
return string.match(reAsciiWord) || [];
}
module.exports = asciiWords;

View File

@ -0,0 +1,20 @@
var baseAssignValue = require('./_baseAssignValue'),
eq = require('./eq');
/**
* This function is like `assignValue` except that it doesn't assign
* `undefined` values.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignMergeValue(object, key, value) {
if ((value !== undefined && !eq(object[key], value)) ||
(value === undefined && !(key in object))) {
baseAssignValue(object, key, value);
}
}
module.exports = assignMergeValue;

View File

@ -0,0 +1,28 @@
var baseAssignValue = require('./_baseAssignValue'),
eq = require('./eq');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignValue(object, key, value) {
var objValue = object[key];
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
(value === undefined && !(key in object))) {
baseAssignValue(object, key, value);
}
}
module.exports = assignValue;

View File

@ -0,0 +1,21 @@
var eq = require('./eq');
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
module.exports = assocIndexOf;

View File

@ -0,0 +1,21 @@
var baseEach = require('./_baseEach');
/**
* Aggregates elements of `collection` on `accumulator` with keys transformed
* by `iteratee` and values set by `setter`.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} setter The function to set `accumulator` values.
* @param {Function} iteratee The iteratee to transform keys.
* @param {Object} accumulator The initial aggregated object.
* @returns {Function} Returns `accumulator`.
*/
function baseAggregator(collection, setter, iteratee, accumulator) {
baseEach(collection, function(value, key, collection) {
setter(accumulator, value, iteratee(value), collection);
});
return accumulator;
}
module.exports = baseAggregator;

View File

@ -0,0 +1,17 @@
var copyObject = require('./_copyObject'),
keys = require('./keys');
/**
* The base implementation of `_.assign` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
return object && copyObject(source, keys(source), object);
}
module.exports = baseAssign;

View File

@ -0,0 +1,17 @@
var copyObject = require('./_copyObject'),
keysIn = require('./keysIn');
/**
* The base implementation of `_.assignIn` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssignIn(object, source) {
return object && copyObject(source, keysIn(source), object);
}
module.exports = baseAssignIn;

Some files were not shown because too many files have changed in this diff Show More